我正在尝试在 Angular 2(最终版本)中编写一个具有登录和记住用户功能的应用程序。 我试图理解其中的原理。
1-用户输入登录名和密码,然后单击连接
2- 使用用户登录名和密码对 Web 服务进行 Angular2 请求
3- Webservices 创建一个 token 并将其存储在数据库中
4- Web 服务将其发送回前端。
但是前端如何处理 token 呢? 它是否将其存储在 localStorage 中?
记住我:
我已阅读此主题 What is the best way to implement "remember me" for a website?
我知道我们需要一个 token ,并检查每个页面是否存在该 token 以及 db 中是否存在该 token 。
但是它是与登录 token 不同的 token 吗? 我是否将其存储在 localStorage、sessionStorage 中或作为 cookie?
有人可以向我清楚地解释这一切吗? 或者,如果您有任何清晰的主题、教程或可理解的应用程序代码,我将非常高兴。
最佳答案
您可能想看看JWT 。其工作原理如下:
服务器端: 在您的 Web 服务或 Web api 登录 Controller 中,有登录方法,该方法将接受用户名和密码并使用 key 生成 token 。
public string Login(string username, string password)
{
if (!VerifyUserPassword(username, password))
return "Wrong access";
List<Claim> claims = GetUserClaims(username);
RSACryptoServiceProvider publicAndPrivate = new RSACryptoServiceProvider();
publicAndPrivate.FromXmlString(File.ReadAllText(HostingEnvironment.MapPath("~/AppKey.xml")));
JwtSecurityToken jwtToken = new JwtSecurityToken
(
issuer: "http://example.com",
audience: "http://receiver.com",
claims: claims,
signingCredentials: new SigningCredentials(new RsaSecurityKey(publicAndPrivate), SecurityAlgorithms.RsaSha256Signature),
expires: DateTime.Now.AddDays(1)
);
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
string tokenString = tokenHandler.WriteToken(jwtToken);
return tokenString;
}
请记住,此处使用的“AppKey.xml”文件是签署 token 的 key ,稍后将使用该文件来解码 token 。然后您可以创建 customAuthorizeAttribute (在 Web api 中不确定 Web 服务,但应该有另一种方法)来使用之前使用的 key 文件来验证 token ,如下所示。
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
AuthenticationHeaderValue token = actionContext.Request.Headers.Authorization;
if (ValidateToken(token.ToString()))
return;
else
throw new HttpResponseException(System.Net.HttpStatusCode.Unauthorized);
}
private bool ValidateToken(string TokenString)
{
bool result = false;
try
{
SecurityToken securityToken = new JwtSecurityToken(TokenString);
JwtSecurityTokenHandler securityTokenHandler = new JwtSecurityTokenHandler();
RSACryptoServiceProvider publicAndPrivate = new RSACryptoServiceProvider();
publicAndPrivate.FromXmlString(File.ReadAllText(HostingEnvironment.MapPath("~/AppKey.xml")));
TokenValidationParameters validationParameters = new TokenValidationParameters()
{
ValidIssuer = "http://example.com",
ValidAudience = "http://receiver.com",
IssuerSigningKey = new RsaSecurityKey(publicAndPrivate)
};
ClaimsPrincipal claimsPrincipal = securityTokenHandler.ValidateToken(TokenString, validationParameters, out securityToken);
result = true;
}
catch (Exception ex)
{
result = false;
}
return result;
}
}
现在,无论您想在何处使用授权,都可以将此 customAuthoorize 属性放置在方法上,如下所示。
[CustomAuthorize]
[HttpPost]
public string TestAuthorization()
{
return "Success!";
}
客户端: 在 Angular2 应用程序中实现服务,该服务将在将请求发送到服务器之前将 token 注入(inject)授权 header ,如下所示。
export class DataService {
constructor(private http: Http) { }
postService(url: string, body: any, options?: RequestOptions): Observable<any> {
let tempOptions: RequestOptions = options;
if (tempOptions)
tempOptions.headers.append('Authorization', localStorage.getItem("appToken"));
else {
tempOptions = new RequestOptions();
let hd = new Headers();
hd.append('Authorization', localStorage.getItem("appToken"));
tempOptions.headers = hd;
}
return this.http.post(url, body, tempOptions).map((result: Response) => <any>result.json());
}
}
然后在实际的组件类中简单地实现它。
Login() {
this.myDataService.postService('http://YOURAPI/Login?username=xyz&password=xyz', null).subscribe(result => {
let token = result;
localStorage.setItem("appToken",token);
this.message="Login successful";
});
在登录方法中将 token 存储到本地存储,之后每当您通过刚刚创建的 Angular 服务调用服务器方法时,授权 token 将被注入(inject)到请求 header 中。
YourMethod() {
this.myDataService.postService('http://YourAPI/TestAuthorization', null).subscribe(result => {
this.message = result;
});
一切都准备好了!享受吧!
关于Angular2 - 具有登录和记住用户功能的应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44267057/