我想将jwt令牌发送到客户端。 但是当返回jwt令牌时,它会显示一些错误。 当我尝试登录时,就会发生此错误。 最初,我将项目数据库设置为sqlite,然后将其设置为mysql。我认为在更改数据库后会发生此问题 这是代码
启动类
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>(s => s.UseMySql(Configuration.GetConnectionString("DefaultConnection")));
IdentityBuilder builder = services.AddIdentityCore<User>(opt =>
{
opt.Password.RequireDigit = false;
opt.Password.RequiredLength = 4;
opt.Password.RequireNonAlphanumeric = false;
opt.Password.RequireUppercase = false;
});
builder = new IdentityBuilder(builder.UserType, typeof(Role), builder.Services);
builder.AddEntityFrameworkStores<DataContext>();
builder.AddRoleValidator<RoleValidator<Role>>();
builder.AddRoleManager<RoleManager<Role>>();
builder.AddSignInManager<SignInManager<User>>();
// services.AddAuthorization(options => {
// options.AddPolicy("RequireAdminRole", policy => policy.RequireRole("Admin"));
// options.AddPolicy("SuperAdminPhotoRole", policy => policy.RequireRole("SuperAdmin"));
// });
services.AddMvc(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddJsonOptions(opt =>
{
opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
services.AddCors();
services.AddAutoMapper();
services.AddTransient<Seed>();
services.AddScoped<IAuthRepository, AuthRepository>();
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
};
});
services.AddScoped<LogUserActivity>();
}
// 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());
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc();
}
}
这是Auth控制器代码
[AllowAnonymous]
[Route("api/[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
private readonly IAuthRepository _repo;
private readonly IConfiguration _config;
private readonly IMapper _mapper;
private readonly UserManager<User> _userManager;
private readonly SignInManager<User> _signInManager;
public AuthController(IConfiguration config,
IMapper mapper, UserManager<User> userManager,
SignInManager<User> signInManager)
{
_signInManager = signInManager;
_userManager = userManager;
_config = config;
_mapper = mapper;
}
[HttpPost("register")]
public async Task<IActionResult> Register(UserForRegisterDto userForRegisterDto)
{
try
{
var userToCreate = _mapper.Map<User>(userForRegisterDto);
var result = await _userManager.CreateAsync(userToCreate, userForRegisterDto.Password);
var userToReturn = _mapper.Map<UserForDetailedDto>(userToCreate);
if (result.Succeeded)
{
return CreatedAtRoute("GetUser", new { Controller = "Users", id = userToReturn.Id }, userToReturn);
}
return BadRequest(result.Errors);
}
catch (Exception e)
{
return BadRequest("An error occurs while registering:" + e.ToString());
}
}
[HttpPost("login")]
public async Task<IActionResult> Login(UserForLoginDto userForLoginDto)
{
try
{
var user = await _userManager.FindByNameAsync(userForLoginDto.Username);
var result = await _signInManager.CheckPasswordSignInAsync(user, userForLoginDto.Password, false);
if (result.Succeeded)
{
var appUser = await _userManager.Users.Include(p => p.Photos)
.FirstOrDefaultAsync(u => u.NormalizedUserName == userForLoginDto.Username.ToUpper());
var userToReturn = _mapper.Map<UserForListDto>(appUser);
return Ok(new
{
token = GenerateJwtToken(appUser),
user = userToReturn
});
}
return Unauthorized();
}
catch (Exception e)
{
return BadRequest("An error occurs while loggin:" + e.ToString());
}
}
private async Task<string> GenerateJwtToken(User user)
{
var claims = new List<Claim> {
new Claim(ClaimTypes.NameIdentifier,user.Id.ToString()),
new Claim(ClaimTypes.Name, user.UserName)
};
var roles = await _userManager.GetRolesAsync(user);
foreach (var role in roles)
{
claims.Add(new Claim(ClaimTypes.Role, role));
}
var key = new SymmetricSecurityKey(Encoding.UTF8
.GetBytes(_config.GetSection("AppSettings:Token").Value));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);
var tokenDescripter = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.Now.AddDays(1),
SigningCredentials = creds
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescripter);
return tokenHandler.WriteToken(token);
}
}
这是显示的错误
Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HLJ0BIR31H6O", Request id "0HLJ0BIR31H6O:00000001": An unhandled exception was thrown by the application.
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.PlatformNotSupportedException: This instance contains state that cannot be serialized and deserialized on this platform.
at System.Security.Claims.ClaimsPrincipal.OnSerializingMethod(StreamingContext context)
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at Newtonsoft.Json.Serialization.JsonContract.<>c__DisplayClass57_0.<CreateSerializationCallback>b__0(Object o, StreamingContext context)
at Newtonsoft.Json.Serialization.JsonContract.InvokeOnSerializing(Object o, StreamingContext context)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.OnSerializing(JsonWriter writer, JsonContract contract, Object value)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
答案 0 :(得分:3)
return Ok(new {
token = GenerateJwtToken(appUser).Result,
user = userToReturn
});
由于GenerateJwtToken是异步方法,因此您需要获取结果。这应该可以解决您的问题。
谢谢