2017-05-30 74 views
2

我想用登錄和Angular 2(最終版本)編寫應用程序並記住用戶功能。 我試圖理解這個原理。Angular2 - 應用程序與登錄和記住用戶

1-用戶輸入他的帳號和密碼和對帶有用戶登錄名和密碼web服務連接

2- Angular2請求單擊

3- WEBSERVICES創建令牌並將其存儲在數據庫

4- Web服務將其發送回前端。

但是前面用令牌做了什麼? 它是否將其存儲在localStorage中?

了rememberMe:

我讀過這個話題What is the best way to implement "remember me" for a website?

我明白,我們需要一個令牌,並在每一頁上檢查,如果這個標記存在於餅乾,如果它在數據庫相同。

但它是一個不同的令牌比登錄? 我將它存儲在localStorage,sessionStorage中還是作爲cookie?

有人可以向我清楚地解釋這一切嗎? 或者如果你有任何明確的主題,教程或應用程序代碼可以理解,我會很高興。

回答

3

你可以看看JWT。它的工作原理如下方式:

服務器端: 在您的網絡服務或網絡API登錄控制器已經登錄方法將接受用戶名和PWD和使用密鑰生成令牌。

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」文件簽署,這將在以後用於令牌解碼令牌中的密鑰。然後,您可以創建customAuthorizeAttribute(在web api中不確定Web服務,但應該有另一種方法)使用之前使用的密鑰文件驗證令牌。

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應用實施服務,將注入到令牌授權頭將請求發送到服務器,你這個樣子了。

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"; 
}); 

在登錄方法令牌存儲到本地存儲和以後,無論何時調用,通過該剛創建的角度業務服務器的方法,授權令牌將在請求報頭被注入。

YourMethod() { 
this.myDataService.postService('http://YourAPI/TestAuthorization', null).subscribe(result => { 
    this.message = result; 
}); 

你一切都安定!請享用!

+0

所以如果我理解的很好,每次用戶登錄時,都會從他的密碼+密鑰生成一個新的令牌?但如果它是一個新的,你怎麼能匹配db中的令牌? 如何填充文件AppKey.xml中包含的密鑰?生成?或由我選擇? 對於前端,關閉瀏覽器時是否擦除本地存儲中包含的數據? 還是記住我的功能通過設置令牌的過期時間? – anais1477

+0

這只是一個示例代碼。您需要根據您的要求對其進行修改。此代碼將爲每個登錄名生成新的令牌。您不需要在db中存儲令牌,因爲我們使用密鑰對其進行簽名並使用相同的密鑰對其進行驗證。有很多方法可以生成密鑰。只是谷歌周圍,或者我會發布一些代碼,當我得到時間。您可以向令牌添加到期時間,或者可以使用刷新令牌的概念。 – Prabi

相關問題