In this tutorial, we will discuss Angular 5 Login and Logout with Web API Using Token Based Authentication. This is a continuation to the previous article – User Registration in Angular 5 with Web API.
Content discussed :
- Design Login Form in Angular 5 application.
- Web API Token Based Authentication using OWIN and ASP.Net Identity.
- Send Token From Angular HTTP Interceptor.
Here is the complete article list.
- User Registration.
- Login & Logout using Token.
- Role Based Authorization.
GitHub link for the project project : https://goo.gl/zWCW7U.
Following tools and modules are used for this project :
– Angular CLI
– Angular 5
– Materialize CSS (front end framework)
– VS Code & Visual Studio Editor
We assume that you have installed required packages and software for Angular 5 development.
Introduction
In previous article we have created angular 5 user registration form and inserted new users into Web API Project using ASP.NET Identity. Here we will update the angular 5 and Web API projects for token based user authentication.
Structure of Updated Angular 5 Project
Here is the final structure of Angular Application.
● src
+---● app
| +--● user
| |--user.component.ts|.html|.css
| +--● sign-in
| | |--sign-in.component.ts|.html|.css
| |
| +--● sign-up
| | |--sign-up.component.ts|.html|.css
| |
| +--● shared
| |--user.service.ts
| |--user.model.ts
|
+---● home
| |--home.component.ts|.html|.css
|
|---● routes.ts
|
+---● auth
| |--auth.guard.ts
| |--auth.interceptor.ts
sign-up component is added in previous article, In this project user component will be the parent component for sign-in and sign-up component. Login form can created using sign-in component. home component will display dashboard for the application. After successful authentication, we opens home component for the user. Inside routes.ts file, we will configure routing for the application. Remaining auth folder can discussed later.
So here we need 3 additional components – home,user and sign-in component. In-order to create these components execute following Angular CLI commands.
ng g c home
ng g c user
//from user component folder - user
ng g c sign-in
sign-up component is created in previous tutorial, as per the project design, we need to move the sign-up folder inside user folder. These components should be added to app.module.ts file as follows.
Because of sign-up component location change, we need to fix some broken import statement with User and UserService classes as follows.
Now let me update the global style sheet – styles.css with complete CSS rules for this application.
button.btn-submit{
background-color: #38547b;
color: #fff;
width: 100%;
}
button.btn-submit:focus,button.btn-submit:hover{
background-color: #38547b;
}
input.ng-invalid.ng-dirty{
border-bottom-color : #e91e63 !important;
box-shadow: 0 1px 0 0 #e91e63 !important;
}
/*for error div i*/
div.error-message i{
vertical-align: middle !important;
}
/*for tab control*/
.tabs{
height: 65px;
}
.tabs .tab{
text-transform : none !important;
line-height: 65px;
height: 65px;
}
.tabs .tab a{
font-size: 25px;
color: grey !important;
}
.tabs .tab a.active{
background-color: #fff !important;
}
For this project, I will use Material Icons instead Font Awesome Icons. For that update index.html with icon style sheet reference.
Inside the body tag we haveclasses from materialize framework to add some background color. Update app.component.html as follows.
This router-outlet tag will be replaced with current component html as per router configuration.
In sign-up component, user registration form is enclosed inside card div from Materialize CSS(designed in previous article). Now let’s remove the card div and we will just keep the user registration form inside the html as follows.
Design Tab Control
First of all we have to design user component. Inside that we’ll add an outer div for both sign-in and sign-up components. For that I’ll add Materialize CSS card control with two tabs.
router-outlet inside this component will be replaced by either sign-in or sign-up component.
Configure Application Route
First of all create new file – routes.ts. Then use following rout configurations.
For sign-in and login path we have used one parent component (user component – for outer div) and inside the children we have Sign In and Sign Up component. With this file we have configured application routing, now we need to tell the application to follow these routes. Update app.module.ts file.
Now we can use this router path in user component tab control.
Here routerLinkActive is used to apply css class ‘active’, when we click on these anchor links.
Design Login Form in Angular 5
Now let’s design the login form, Open and update the sign-in component html file as follows.
Here we have a template driven form. In-order to work this form, make sure that FormsModule is added to app.module.ts file. Both username and password text boxes are mandatory fields and hence required attribute is added to the inputs fields. Now we have a login form like this.
Token Based User Authentication in Web API
Now let’s update the Web API Project for Token Based Authentication. In-order to implement user authentication we need OWIN(Open Web Interface For .Net Applications). It act as a middle-ware between Asp.Net Application and IIS Server. First of all install required NuGet Packages.
In Solution explorer, Right Click On References. then click on Manage NuGet Packages. then do an online search for following packages and install them.
- Microsoft ASP.NET Identity Owin
- Microsoft.Owin.Host.SystemWeb
- Microsoft.Owin.Cors
In-order to work with OWIN, we have to create OWIN Startup class. For that right click on Project > New Item, then Search for OWIN Startup class. and I’ll name the file as Startup.cs. Now you can update the class as follows.
Let’s discuss line by line.
app.UseCors function will enable CORS(Cross Origin Resource Sharing) inside the application. In previous article, we already enabled CORS in WebApiConfig.cs file. Now you can comment that line.
After Enabling CORS, we have an object of OAuthAuthorizationServerOptions. inside that we have following properties
- TokenEndpointPath – Specifies URL to Authenticate a user. In this Case we have to make HttpPost Request with username and password into http:localhost:portnumber/token URL. If given user credentials are valid, it will return an access token.
- Provider – we set provider as ApplicationOAuthProvider class object. inside that we define how do we authenticate a user from database.
- AccessTokenExpireTimeSpan – access token from token request response will have an expire time. In this case it is 60 minutes/1 Hour.
- AllowInsecureHttp – flag to secure token request from unsecured HTTP.
Let’s create the ApplicationOAuthProvider provider class to validate username and password.
ApplicationOAuthProvider is inherited from OAuthAuthorizationServerProvider class. Inside that we have overridden two functions.
- ValidateClientAuthentication() – used tovalidate client device based on clientID and secret code. but in this project we’ll not authenticate client device.
- GrantResourceOwnerCredentials() – authenticate a user with given username and password. If authentication is successful then we save user details as Claims Identity. It can be used to retrieve user details without DB interaction.
Now back to VS Code Editor. Let’s make token POST request on login form submission.
Token Request From Angular 5 Project
First of all create a function inside UserService class to make a token request as follows.
Along with userName and password you have to pass grant_type as password. With HttpHeader, we have set Content-Type as application/x-www-urlencoded. Additional No-Auth property is set to True. we can discuss need of this No-Auth property later.
Now open sign-in component html and then wire up a submit event
No let’s define the function inside the component typescript file.
Inside the OnSubmit() function, you have two arrow function, for success and error response. if user authentication is successful, we save the accessToken in localStorage (in web browser). because we need this token to authenticate the user in this angular 5. Finally we will navigate the user to home component.
If authentication is fails, isLogin is set to true, based on this property we will show an error message just above the login form.
Angular 5 User Authentication Using Token
Now let’s implement user authentication in this angular 5 project. First of all, I will create a new folder auth inside the app folder. Now lets create guard class for user authentication.
# from auth folder
ng g g auth
So it will create auth.guard.ts file, inside that we’ll modify the canActivate() function as follows.
with canActivate() function we will check whether an user is authenticated or not using localStorage – userToken.
if not not authenticate we will send him to login form. in-order to work this guard we have to do some additional work.
open app.module.ts file, then add AuthGuard class inside providers array.
Now update routes.ts file by adding guard class to routes which is to be authenticated.
In this case, home route must authenticated so we have added canActivate array with AuthGuard class.
Consume Web API Methods with Authorization
To consume Web API method with Authorize Attribute, we need to send access token along with the request. To demonstrate this process, let me add a Web API method with Authorize attribute.
Inside the Web API project, I’ll add a new Web API method inside AccountController as follows.
This method returns few user claims saved during user authentication. Now let’s call this Web API from Home Component. First of all update the home.component.html as follows.
Update the component typescript file.
Now let’s define the getUserClaims() function inside the UserService class.
So inside the home component ngOnInit Lifecyle-Hook, we consumed the GetUserClaims method and we have shown the result in home component html.
Here we didn’t append access token in the request, we can discuss that in a bit. We have a logout button in home component top Navbar. Logout() function is wired up to the logout button click event.
HTTP Interceptor in Angular 5
In UserService class function getUserClaims(), To consume the Web API method we have not appended the accessToken. It would be difficult to append accessToken to every Web API call and we have to handle the 401 UnAuthorized Response in each of them( if access token expires).
To do this task, we have a common place – HTTP Interceptor. For that I will create auth.interceptor.ts file in auth folder as follows.
Here AuthInterceptor class is inherited from HttpInterceptor class.
With the first IF statement, we will check the condition No-Auth is True/False. if it is true we don’t need to append the access token. So you can set No-Auth as true for web api calls which does not need authorization.
Then we check whether the user is authenticated or not. if authenticated then we will append the access token in request header. we must use the prefix Bearer while passing Authorization Access Token in request header. Inside the error function, we handle 401 Unauthorized Status Code – most often it can appear due to token expiration.
That’s it. Let me know your doubts and feedback in the comment box below. In the next part, we will discuss Role Based Authorization in Angular 5 with Web API.
Good explanation.. really.. thanks.
HELLO HOW TO MAKE A LOGIN? with web API of an existing database with users table (id, name, first name, pwd, role); Thank you for your tutorials
thanks
The video is excellent. I learned a lot. It is so much easy than the other web applications (I don’t want to name them… it may offense some people). I do have question to the author if he plan to release any videos soon for Angular and Microsoft API (MVC) with Identity user. Basically, Microsott with pre-package (login, register, logout…) but it is written in RCL (Razors Code Library).. It is good if you stay in Microsoft platform. However, I have added JWT token to the login.cshtml.cs (the code generated in the area/identity/account…). and it is not working at all. On the angular side, the localstorage.getItem(‘token’) always return null.
I wonder any one can give me clues to fix the problem. It would be nice if there is a piece of code that write token to client computer.
To me, it is the WRITETOKEN(token) is the problem child.
Thank you.
thanks for your wonderful feedback.
I’ve updated this tutorial with the latest asp.net core and angular in youtube tutorial here: https://www.youtube.com/watch?v=s2zJ_g-iQvg.
Text Article will be posted soon.
Angular 5 – Registration, Login and Logout with Web API using Token Based Authentication is Nice Tutorials and it’s work good.
Thank u for these tutorials.
i’m trying to develop for My Collage Project(Hybrid app in Ionic 4) can u help me in Update User Data, Show All Data and Change Password for these (Angular 5 – Registration, Login and Logout with Web API using Token Based Authentication).
var userStore = new UserStore(new ApplicationDbContext());
var manager = new UserManager(userStore);
var user = await manager.FindAsync(context.UserName, context.Password);
if (user != null){
///code
}
Here user is showing null.
manager.FindAsync —-in manager there is no any FindAsync method or property
Could anyone please help me on this to figure out the issue?
Issue is solved.
great Article.
Hi this is a great artilcle. can i have the git hub link for the sample application ?
Just discovered that the action method for “token” is missing in your code example for the web api controller.
I think that the original userAuthentication method used here can rise problems with passwords containing special characters, like “&” and so, because they are sent as url parameters. I think they should be encoded, using something like this:
userAuthentication(userName, password) {
let params = new HttpParams();
params = params.append(“username”,userName);
params = params.append(“password”,password);
params = params.append(“grant_type”,’password’);
var data = params.toString();
var reqHeader = new HttpHeaders({ ‘Content-Type’: ‘application/x-www-urlencoded’,’No-Auth’:’True’ });
return this.http.post(this.rootUrl + ‘/token’, data, { headers: reqHeader });
}
Hope this helps.
Hi
Thanks For Sharing
Local Storage is safe this Sample?
good video and detailed
BONJOUR COMMENT FAIRE UN LOGIN ? avec webapi d’une base de donnée existance avec table users( id,nom,prenom,pwd, role); Merci pour vos tutos
Hi Your article is awesome. Can you please guide me how to use remember me option in login form. thanks
why code not same in github?
Hi
I have a problem,
for auth.interceptor.ts : my VSCode has a problem that is:
Property ‘do’ does not exist on type ‘Observable<HttpEvent>
what am I dong to fix it?
https://stackoverflow.com/questions/45846662/angular-4-http-interceptor-next-handle-do-is-not-a-function
here is the solution
There are changes in angular 5
https://alligator.io/angular/angular-5/
while login i m unable display the user claims in home page and while loading the page it shows this error and in web api action method getuserclaims it unable to hit.
TypeError: You provided ‘undefined’ where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
There is a bug. If the user does not have a token, the function navigates to ‘login/’, but does not return anything. You probabily use the return to subscribe.
I’ve added a next call like so.
else {
this.router.navigateByUrl(‘/login’);
return next.handle(req.clone());
}
Keep in mind that this is not to replace actual token check on the server, it just to add the headers in a single place
have to resolve this error?
nice article. Very much helpful. Thank you for share.
Great job. Thanks for sharing. I am a dot net developer too but unlike you, I am just a beginner and also trying to share all my experience as a beginner. Can I make this post as a reference on my blog? Send me some emails if it’s ok.
sure
Hi, Сan you to show me your db struct? Which fill have in tour tables?
I have error in my project,
Hi,
The tutorial details with video is really outstanding. Thanks for putting in all the efforts.
It would be really great if you migrate current web API project to Asp.Net Core 2.o and provide all authentication/authorization methods by following Asp.Net Core 2.0 standards. Also use JWT Token option instead of basic token based option currently used as it seems JWT Token based authentication/authorization is getting more popular now a days
Do you have same project using JWT token?
Hi
It is working Visual studio ?
It is navigate some other page