Как исправить ошибку «Не удалось проверить токен» в проекте - PullRequest
0 голосов
/ 18 мая 2019

Я пытаюсь получить GET-запрос от Почтальона, и когда я нажимаю «Отправить», я получаю статус 401 неавторизованный. Я подумал, что это может иметь какое-то отношение к базе данных, потому что, когда я пытаюсь запустить команду 'dotnet ef database drop', и я обновился на SQLite, пользователи все еще были там. Я не поняла почему. Как решить эту проблему?

POWERSHELL с 'dotnet watch run':

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
  Request starting HTTP/1.1 GET http://localhost:5000/api/users
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[1]
  Failed to validate the token.
Microsoft.IdentityModel.Tokens.SecurityTokenExpiredException: IDX10223:     Lifetime validation failed. The token is expired. ValidTo: '05/17/2019     01:19:03', Current time: '05/18/2019 14:22:01'.
at Microsoft.IdentityModel.Tokens.Validators.ValidateLifetime(Nullable`1     notBefore, Nullable`1 expires, SecurityToken securityToken,     TokenValidationParameters validationParameters)
at     System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateLifetime(Nullable`1 notBefore, Nullable`1 expires, JwtSecurityToken jwtToken, TokenValidationParameters validationParameters)
at      System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateTokenPayload(JwtSecurityToken jwtToken, TokenValidationParameters validationParameters)
at     System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
at     Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[7]
  Bearer was not authenticated. Failure message: IDX10223: Lifetime validation failed. The token is expired. ValidTo: '05/17/2019 01:19:03', Current time: '05/18/2019 14:22:01'.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[3]
  Route matched with {action = "GetUsers", controller = "Users"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] GetUsers() on controller DatingApp.API.Controllers.UsersController (DatingApp.API).
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
  Authorization failed.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[3]
  Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
info: Microsoft.AspNetCore.Mvc.ChallengeResult[1]
  Executing ChallengeResult with authentication schemes ().
info:  Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[12]
  AuthenticationScheme: Bearer was challenged.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
  Executed action DatingApp.API.Controllers.UsersController.GetUsers     (DatingApp.API) in 29.9597ms
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
  Request finished in 317.5588ms 401

auth.service.ts:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import {map} from'rxjs/operators';
import {JwtHelperService} from '@auth0/angular-jwt';


@Injectable({ //inject to service
providedIn: 'root'
})
export class AuthService {
baseUrl = 'http://localhost:5000/api/auth/';
jwtHelper = new JwtHelperService();
decodedToken: any;

constructor(private http: HttpClient) { }

login(model: any) {
return this.http.post(this.baseUrl + 'login', model).pipe(
map((response: any) => {
  const user = response;
  if (user) {
    localStorage.setItem('token', user.token);
    this.decodedToken = this.jwtHelper.decodeToken(user.token);
    console.log(this.decodedToken);
  }
})
)
}

register(model: any) { //need authservice in register component     constructor
return this.http.post(this.baseUrl + 'register', model);
}

loggedIn() {
const token = localStorage.getItem('token'); //check valid token
return !this.jwtHelper.isTokenExpired(token);
}


}

AuthController.cs

using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using DatingApp.API.Data;
using DatingApp.API.Dtos;
using DatingApp.API.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens; //Symmetric Security Keys

namespace DatingApp.API.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
    private readonly IAuthRepository _repo;
    private readonly IConfiguration _config;
    public AuthController(IAuthRepository repo, IConfiguration config)
    {
        _config = config;
        _repo = repo;
    }

    [HttpPost("register")]
    public async Task<IActionResult> Register(UserForRegisterDto userForRegisterDto) //get username and password, [FromBody] gives hint where info is
    {
        userForRegisterDto.Username = userForRegisterDto.Username.ToLower(); //make username lowercase

        if (await _repo.UserExists(userForRegisterDto.Username)) //check if User exist
            return BadRequest("Username already exist"); //BadRequist requires ControllerBase

        var userToCreate = new User
        {
            Username = userForRegisterDto.Username //APIModels
        };

        var createdUser = await _repo.Register(userToCreate, userForRegisterDto.Password);

        return StatusCode(201);
    }

    [HttpPost("login")]
    public async Task<IActionResult> Login(UserForLoginDto userForLoginDto)
    {
        var userFromRepo = await _repo.Login(userForLoginDto.Username.ToLower(), userForLoginDto.Password);

        if (userFromRepo == null)
            return Unauthorized();

        var claims = new[]
        {
            new Claim(ClaimTypes.NameIdentifier, userFromRepo.Id.ToString()), //token claims Id
            new Claim(ClaimTypes.Name, userFromRepo.Username) //token claims username
        };

        var key = new SymmetricSecurityKey(Encoding.UTF8
        .GetBytes(_config.GetSection("AppSettings:Token").Value)); //MUST set TOKEN in appsettings.json

        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);

        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(claims),
            Expires = DateTime.Now.AddDays(1),
            SigningCredentials = creds
        };

        var tokenHandler = new JwtSecurityTokenHandler(); //to make token

        var token = tokenHandler.CreateToken(tokenDescriptor);

        return Ok(new
        {
            token = tokenHandler.WriteToken(token)
        });

    }

}
}

Startup.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DatingApp.API.Data;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.EntityFrameworkCore; //ONLY 2.1.0 works
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using System.Net;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Http;
using DatingApp.API.Helpers;
using AutoMapper;

namespace DatingApp.API
{
public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<DataContext>(x => x.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
            .AddJsonOptions(opt => {
                opt.SerializerSettings.ReferenceLoopHandling = 
                Newtonsoft.Json.ReferenceLoopHandling.Ignore; //For loop error
            });
        services.AddCors(); //add this  
        services.AddAutoMapper(); //using 4.0.1 check csproj file
        services.AddTransient<Seed>(); //JSON config
        services.AddScoped<IAuthRepository, AuthRepository>(); //add controllers
        services.AddScoped<IDatingRepository, DatingRepository>();
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options => {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII
                .GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
                ValidateIssuer = false,
                ValidateAudience = false
            };
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, Seed seeder)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler(builder => {
                builder.Run(async context => {
                    context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;

                    var error = context.Features.Get<IExceptionHandlerFeature>();
                    if (error != null)
                    {
                        context.Response.AddApplicationError(error.Error.Message);
                        await context.Response.WriteAsync(error.Error.Message);
                    }
                });
            });
            //app.UseHsts();
        }

        //app.UseHttpsRedirection();
        //seeder.SeedUsers();
        app.UseCors(x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()); //add this
        app.UseAuthentication();
        app.UseMvc(); //add this
    }
}
}

Когда я пытаюсь войти на локальный хост: 4200. Я получаю это уведомление об ошибке от alerttify:

функция true Составная функция () {[собственный код]} Функция stopPropagation () {[собственный код]} stopImmediatePropagation () {[собственный код]} функция предотвратите ошибки () {[собственный код]} функция initEvent () {[собственный код]} ошибка [объект XMLHttpRequest] [объект XMLHttpRequest] [объект XMLHttpRequest] 2 true 50126 [объект XMLHttpRequest] [объект XMLHttpRequest] 1 2 3 1 2 4 8 function stopImmediatePropagation () {[собственный код]}

И в веб-консоли я получаю это сообщение об ошибке:

Запрос на перекрестное происхождение заблокирован: одна и та же политика происхождения запрещает чтение удаленный ресурс на http://localhost:5000/api/auth/login. (причина: Отсутствует заголовок CORS «Access-Control-Allow-Origin».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...