Token based authentication in Angular 6 with Web API
Hi All,
In this tutorial I have shown how to do token based authentication with Owin Middleware and WEB API and same has the integration with Angular 6.
If you prefer to watch video, here is the link for same, each and everything is explained about token based authentications with web api and angular 6.
So let us get started:
The basic steps are:
- Angular 6 Login and Logout with Web API Using Token Based Authentication
- Design Login Form in Angular 6 application.
- Web API Token Based Authentication using OWIN and ASP.Net Identity.
Let us start with WEB API:
1. Create one web api project
2. Create a class like below:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace DeepCart.Models
{
public class User
{
[Key]
public int Id { get; set; }
[Required, MinLength(3), MaxLength(50)]
public string UserName { get; set; }
[Required, MinLength(3), MaxLength(50)]
public string Password { get; set; }
}
}
Now build the project.
3. Install fallowing packages in your web api project:
Microsoft.Owin
Microsoft.Owin.Host.SystemWeb
Microsoft.Owin.Security.OAuth
Microsoft.Owin.Security
Microsoft.AspNet.Identity.Owin
Microsoft.Owin.Cors
These packages are the important packages to give the support for owin middleware and OAuth. In this tutorial we will be talking about bearer authentication.
4. Write a provider class like this:
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.OAuth;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web.Http.Cors;
using DeepCart.Models;
using System;
namespace DeepCart.DtProvider {
// This tutorial is by DotNet Techy YouTube Channel
// For more info about channel You can visit this link
// [](https://www.youtube.com/c/dotnettechy)
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class DotNetTechyAuthServerProvider: OAuthAuthorizationServerProvider {
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) {
context.Validated();
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) {
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new [] {
"*"
});
using(var db = new DeepCartContext()) {
if (db != null) {
var user = db.Registrations.ToList();
if (user != null) {
if (!string.IsNullOrEmpty(user.Where(u => u.UserName == context.UserName && u.Password == context.Password).FirstOrDefault().UserName)) {
var currentUser = user.Where(u => u.UserName == context.UserName && u.Password == context.Password).FirstOrDefault();
identity.AddClaim(new Claim("Role", currentUser.Role));
identity.AddClaim(new Claim("Id", Convert.ToString(currentUser.Id)));
var props = new AuthenticationProperties(new Dictionary < string, string > {
{
"DisplayName",
context.UserName
},
{
"Role",
currentUser.Role
}
});
var ticket = new AuthenticationTicket(identity, props);
context.Validated(ticket);
} else {
context.SetError("invalid_grant", "Provided username and password is not matching, Please retry.");
context.Rejected();
}
}
} else {
context.SetError("invalid_grant", "Provided username and password is not matching, Please retry.");
context.Rejected();
}
return;
}
}
}
}
This DotNetTechyAuthServerProvider class is getting inherited from OAuthAuthorizationServerProvider and this comes from Microsoft.Owin.Security.OAuth.
It has two basic methods which needs to be overridden in order to validate user name and password from you database and return the token back if username and password is valid.
First method is : ValidateClientAuthentication
Second Method is: GrantResourceOwnerCredentials
More you will understand by looking at code , what it is doing or else watch this video.
5. Create a class called Startup like below:
using DeepCart.DtProvider;
using Microsoft.Owin;
using Microsoft.Owin.Cors;
using Microsoft.Owin.Security.OAuth;
using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
[assembly: OwinStartup(typeof(DeepCart.Startup))]
namespace DeepCart
{
// This tutorial is by DotNet Techy YouTube Channel
// For more info about channel You can visit this link
//
public class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
var OAuthOptions = new OAuthAuthorizationServerOptions {
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(20),
Provider = new DotNetTechyAuthServerProvider()
};
app.UseOAuthBearerTokens(OAuthOptions);
app.UseOAuthAuthorizationServer(OAuthOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
HttpConfiguration config = new HttpConfiguration();
WebApiConfig.Register(config);
}
public void Configuration(IAppBuilder app) {
//app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
ConfigureAuth(app);
GlobalConfiguration.Configure(WebApiConfig.Register);
}
}
}
This is the imprtant line which is loading Owin when application gets intilized.
[assembly: OwinStartup(typeof(DeepCart.Startup))]
Then in
var OAuthOptions = new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(20),
Provider = new DotNetTechyAuthServerProvider()
};
We are providing our earlier created provider: DotNetTechyAuthServerProvider
6-Testing the access token generation.
Make a request from postman like this:
Where username and password should be from your database, whatever you have given while registration. If you want to watch the video about registration form it will be like this:
DotNetTechyAuthServerProvider
https://youtu.be/SrmShkVhKhU
Here is the screenshot of testing the token.
7-Integrate this access token in angular 6.
So this invloves multiple steps as below-
a) Create a service to call the web api get the token back.
b) Store the token for next request to pass into header
c) Call the validate user method form your login button click event
d)Create a auth guard and override CanActivate method
Service Method
// This tutorial is by DotNet Techy YouTube Channel
// For more info about channel You can visit this link
//
ValidateUser(user: any)
{
var userData = "username=" + user.UserName + "&password=" + user.Password + "&grant_type=password";
var reqHeader = new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded',
'No-Auth': 'True'
});
return this.httpClient.post(this.apiURL + '/token', userData, {
headers: reqHeader
})
.pipe(
map(res => res),
catchError(this.errorHandler)
);
}
Auth Guard
// This tutorial is by DotNet Techy YouTube Channel
// For more info about channel You can visit this link
// https://www.youtube.com/c/dotnettechy
canActivate(): boolean {
if (!this.auth.isAuthenticated()) {
//this.router.navigate(['login']);
console.log('You are not authrised to view this page')
return false;
}
return true;
}
store token in local storage
storeToken(token: string) {
localStorage.setItem("token", token);
}
Once login is success you should call to storeToken method.
If you want all the details info please watch these videos and subscribe my channel and enable the notifications.
This complete tutorial is coming under my YouTube Channel called DotNetTechy and Playlist name is : Angular 6 shopping website