【发布时间】:2020-03-30 19:45:10
【问题描述】:
我遇到了一个新问题 - 就像标题所说的那样。我会设法检查问题发生在哪里,但我无法解决它。我会从头开始。
在后端 (ASP.NET 3.0) 我有一个带有登录方法的类AuthController,它看起来像这样:
[HttpPost("login")]
public async Task<IActionResult> Login(LoginedUserDTO loginedUser)
{
var userToLogin = await _authService.Login(loginedUser.Username.ToLower(), loginedUser.Password);
if (userToLogin is null)
return Unauthorized();
var claims = new[]
{
new Claim(ClaimTypes.NameIdentifier, userToLogin.Id.ToString()),
new Claim(ClaimTypes.Name, userToLogin.Username)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration.GetSection("AppSettings:Token").Value));
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();
var token = tokenHandler.CreateToken(tokenDescriptor);
return Ok(new
{
token = tokenHandler.WriteToken(token)
});
}
长话短说,它在用户登录后创建声明 - 从前端站点看起来一切正常 - 之后令牌被放入浏览器的 LocalStorage 中。
现在有一种方法会引起麻烦:
[HttpPost]
public async Task<IActionResult> CreateTicket(TicketBody ticketBody)
{
//var userId = Guid.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value);
if (ticketBody.CurrentUserId != Guid.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value))
return Unauthorized();
var ticket = await _ticketService.CreateTicket(ticketBody.Id, ticketBody.CurrentUserId);
return new JsonResult(ticket);
}
如您所见,User.FindFirst(ClaimTypes.NameIdentifier) 方法应该获取本地令牌并找到用户,但它甚至没有启动或找到任何东西。问题很奇怪,因为当我在没有 Angular 的情况下使用相同的方法但只使用 Postman 并放置与 Angular 中完全相同的令牌时 - 如果用户是有效用户,这种方法可以找到要解决的声明类型,并且工作正常。但是当我试图从前端使用整个 post 方法时,ClaimTypes 事情根本不起作用。
我错过了什么?来自前端的东西?但是来自前端的方法相当简单。来自前端的 userId 毫无问题地传递给 post 方法 - 它只是在它必须获得声明时中断,但正如我所说 - 当同样的事情通过邮递员时它工作。可能是我没有在这些方法上使用 [Authorize] 的问题吗?但是当我这样做时,我应该如何更改前端(或后端),以便它可以通过 Angular 端的 [Authorize] - 到目前为止,我不确定我应该做什么。
编辑:应@Papa Kojo 的要求 - 我正在添加一些前端代码,我想这些代码是相关的:
从前端登录方法 - 令牌被添加到本地存储。
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);
}
})
);
}
调用 post 方法的代码有一小段,它是 paypal API 的一部分。
onApprove: async (data, actions) => {
const order = await actions.order.capture();
this.paidFor = true;
console.log(order);
this.trackIdBody.id = this.trackObj.trackId;
this.trackIdBody.currentUserId = this.authService.decodedToken.nameid;
console.log(this.trackIdBody);
this.http.post('http://localhost:5000/tickets/', this.trackIdBody).subscribe(response => {
console.log(response);
}, error => {
console.log(error);
});
上面 sn-p 中的this.trackIdBody 是具有两个值的 JSON - 它正在被后端在 HttpPost CreateTicket 方法中正确接收。
也许从前端将令牌放入 localStorage 是不够的?但是,当前端调用它时,这些声明也在后端的登录方法中正确地提出。
【问题讨论】:
-
您应该检查您的网络以查看是否有任何请求/错误。此外,一些前端代码将有助于解决这个问题
-
我已经编辑了代码。
-
stackoverflow.com/questions/62853455/… 请看这里,需要帮助。
标签: c# asp.net angular typescript