你可以看看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;
});
你一切都安定!請享用!
所以如果我理解的很好,每次用戶登錄時,都會從他的密碼+密鑰生成一個新的令牌?但如果它是一個新的,你怎麼能匹配db中的令牌? 如何填充文件AppKey.xml中包含的密鑰?生成?或由我選擇? 對於前端,關閉瀏覽器時是否擦除本地存儲中包含的數據? 還是記住我的功能通過設置令牌的過期時間? – anais1477
這只是一個示例代碼。您需要根據您的要求對其進行修改。此代碼將爲每個登錄名生成新的令牌。您不需要在db中存儲令牌,因爲我們使用密鑰對其進行簽名並使用相同的密鑰對其進行驗證。有很多方法可以生成密鑰。只是谷歌周圍,或者我會發布一些代碼,當我得到時間。您可以向令牌添加到期時間,或者可以使用刷新令牌的概念。 – Prabi