2

I'm trying to write an application in Angular 2 (final version) with login and remember user functions. I tried to understand the principle of this.

1- The user enter his login and password and click on connect

2- Angular2 request on webservices with user login and password

3- Webservices creates a token and store it in the db

4- Web services send it back to the front.

But what the front does with the token ? Does it store it in localStorage ?

RememberMe:

I've read this topic What is the best way to implement "remember me" for a website?

I understood that we need a token and check on each page if this token is present in cookies and if it's the same in db.

But is it a different token than the one for the login ? Do I store it in the localStorage, sessionStorage or as a cookie ?

Do someone can explain all of this clearly to me ? Or if you have any clear topic, tutorial or application code understandable I would be very pleased.

anais1477
  • 466
  • 1
  • 17
  • 36

1 Answers1

4

You may wana take a look at JWT. The way it works as below:

Server Side: In your web service or web api Login controller have login method which will accept username and pwd and generate token using key.

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

remember "AppKey.xml" file used here is the key to sign the token which will be used later to decode the token. Then you can create customAuthorizeAttribute (in web api not sure about web services but there should be another way) to validate the token using key file used earlier like this.

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

so now wherever you want to use authorization you can just place this customAuthoorize attribute on the method like this.

[CustomAuthorize]
    [HttpPost]
    public string TestAuthorization()
    {
        return "Success!";
    }

Client Side: In Angular2 application implement service which will inject token into authorization header before sending the request to server for you like this.

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());

}

}

Then in actual component class simply implement it.

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

in login method store the token to local storage and after that whenever you call server methods through the angular service which you just created, authorization token will be injected in the request header.

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

You are all set! Enjoy!

Prabi
  • 173
  • 1
  • 14
  • So if i've understood well, each time an user log in, a new token is generated from his password + key ? But how can you match the token in db if it's a new one ? How does the key contained in the file AppKey.xml is filled ? generated ? or chose by me ? For front end, do the data contained in local storage is wiped when closing the browser ? Or the remember me function works by setting an expired time to the token ? – anais1477 May 31 '17 at 08:41
  • this is just a sample code. You need to modify it as per your requirement. This code will generate new token for each login. You don't need to store token in db as we are signing it with key and validating it back with same key. There are many ways to generate keys. Just google around it or I will post some code when I get time. You can add expiration time to the token or there is concept of refresh token which you can use. – Prabi May 31 '17 at 15:18