Login and Signup with API in Angular 17
Modern Angular: Angular Standalone Components
Subscribe to our Angular newsletter and get Modern Angular ebook!
In this tutorial, we'll learn how to build login and signup pages with Angular 17. we'll use HTML and CSS to create the pages then use Angular code to build the login and signup forms and get the login and signup data from the forms using a reactive approach and then submit it to the auth endpoint using HttpClient.
Setting Up the Authentication Backend
We'll use this Node.js app from https://github.com/techiediaries/node-mongoose-jwt
which provides an authentication backend so make sure you have MongoDB installed in your system then clone the repo, navigate inside of it and run the following command:
npm install
Next create an .env
file and add the following contents:
CONNECTION_STRING= mongodb://127.0.0.1:27017/myapp
JWT_SECRET= secret123456789
Next, run the backend using this command:
npm start
You app JWT authentication backend will be listening at http://localhost:3000
.
Setting Up Angular 17 Authentication Frontend
Now let's get started with our Angular 17 frontend. Open a new terminal and create a new project using the ng new
command then navigate inside your project and create three components for login, signup and admin:
ng g c pages/login
ng g c pages/signup
ng g c pages/admin
We also need to create an authentication service and guard using these commands:
ng g s auth/auth
ng g guard auth/auth
Choose CanActivate
for the authentication guard:
❯◉ CanActivate
◯ CanActivateChild
◯ CanDeactivate
◯ CanMatch
Then press Enter.
Routing Configuration
Next, we need to add the routes to different components and protect the admin component with the authentication guard. Open the src/app/app.routes.ts
file and update it as follows:
import { Routes } from '@angular/router';
import { LoginComponent } from './pages/login/login.component';
import { SignupComponent } from './pages/signup/signup.component';
import { AdminComponent } from './pages/admin/admin.component';
import { authGuard } from './auth/auth.guard';
export const routes: Routes = [
{
path: '', redirectTo: '/login', pathMatch: 'full'
},
{
path: 'login', component: LoginComponent
},
{
path: 'signup', component: SignupComponent
},
{
path: 'admin', component: AdminComponent, canActivate: [authGuard]
}
];
As you can see we are using the redirectTo
attribute to redirect users to the login page when they visit the home path and the canActivate
attribute to protect the admin page from non authenticated users. We'll implement the authentication guard later.
Implementing the Authentication Service
We'll be using the HttpClient
service for communicating with authentication backend so we'll need to provide it first. Open the src/app/app.config.ts
file and add the following import:
import { provideHttpClient } from '@angular/common/http';
Next, call provideHttpClient()
inside the providers
array:
export const appConfig: ApplicationConfig = {
providers: [provideRouter(routes), provideHttpClient()]
};
Next, let's implement the authentication service. Open the src/app/auth/auth.service.ts
file and start by adding the following imports:
import { HttpClient } from '@angular/common/http';
import { inject } from '@angular/core';
import { tap } from 'rxjs/operators';
In the authentication service, inject the HttpClient
service using the inject
method and define a base URL that contains the URL of our auth backend:
httpClient = inject(HttpClient);
baseUrl = 'http://localhost:3000/api';
Next, define the signup()
method of the authentication service:
signup(data: any) {
return this.httpClient.post(`${this.baseUrl}/register`, data);
}
Define the login()
method of the authentication service:
login(data: any) {
return this.httpClient.post(`${this.baseUrl}/login`, data)
.pipe(tap((result) => {
localStorage.setItem('authUser', JSON.stringify(result));
}));
}
Next, define the logout()
method:
logout() {
localStorage.removeItem('authUser');
}
Finally define the isLoggedIn()
method:
isLoggedIn() {
return localStorage.getItem('authUser') !== null;
}
Implementing the Authentication Guard
Next, let's implement the authentication guard. Open the src/app/auth/auth.guard.ts
file and add these imports:
import { inject } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from './auth.service';
Next, inside the authGuard
function inject the authentication and router services:
const authService = inject(AuthService);
const router = inject(Router);
Next, add the following code:
if (authService.isLoggedIn()) {
return true;
}
router.navigate(['/login']);
return false;
This simply tells Angular 17 to navigate the login path if the user is not logged in.
Implementing the Login Component
Next, open the src/app/pages/login/login.component.ts
file and add the following imports:
import { inject } from '@angular/core';
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
import { Router, RouterModule } from '@angular/router';
import { AuthService } from '../../auth/auth.service';
Next, add the reactive forms and router modules inside the imports
array of the login component:
@Component({
selector: 'app-login',
standalone: true,
imports: [ ReactiveFormsModule, RouterModule],
templateUrl: './login.component.html',
styleUrl: './login.component.css'
})
Next, inject the authentication and router services using the inject
method:
authService = inject(AuthService);
router = inject(Router);
Adding the login form
Next, add a form group to the login component:
protected loginForm = new FormGroup({
email: new FormControl('', [Validators.required, Validators.email]),
password: new FormControl('', [Validators.required])
})
The login form contains an email and password controls with validation.
Next, add the onSubmit()
method to the login component:
onSubmit(){
if(this.loginForm.valid){
console.log(this.loginForm.value);
this.authService.login(this.loginForm.value)
.subscribe((data: any) => {
if(this.authService.isLoggedIn()){
this.router.navigate(['/admin']);
}
console.log(data);
});
}
}
This method checks if the form is valid, then attempts to log in with the AuthService
and navigates to an admin page upon successful authentication.
Adding the HTML form for login
Open the src/app/pages/login/login.component.html
file and add the following HTML form:
<div class="login-card">
<div class="card-title">
<h1>Login</h1>
<span>You don't have an account? <a routerLink="/signup">Sign up</a></span>
</div>
<form class="form-group" [formGroup]="loginForm" (ngSubmit)="onSubmit()">
<input name="email" type="email" formControlName="email" placeholder="Email">
<input type="password" formControlName="password" placeholder="Password">
<button>Submit</button>
</form>
</div>
This code is an Angular template for a login form. It uses a combination of HTML, Angular directives, and reactive forms to create a login card with a title, a link to sign up, and a form that submits login information.
Next, open the src/app/pages/login/login.component.css
file and style the login form as follows:
* {
box-sizing: border-box;
}
:host {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(253, 101, 133, 1);
}
.login-card {
display: flex;
flex-direction: column;
margin: 10px 10px;
box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.3);
background-color: #ffffff;
padding: 10px;
border-radius: 10px;
width: 40%;
}
.login-card input {
margin: 5px 0;
width: 100%;
background-color: #e2e2e2;
border: none;
outline: none;
padding: 12px 20px;
border-radius: 4px;
}
.login-card button {
background-color: #4796ff;
color: #ffffff;
font-size: 16px;
outline: none;
border-radius: 5px;
border: none;
padding: 8px 15px;
width: 100%;
}
.card-title h1 {
font-size: 26px;
font-weight: bold;
}
Implementing the Signup Component
Now let's implement the signup page. Open the src/app/pages/signup/signup.component.ts
file and add the following imports:
import { inject } from '@angular/core';
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
import { Router, RouterModule } from '@angular/router';
import { AuthService } from '../../auth/auth.service';
Next, add the reactive forms and router modules to the imports
array of the signup component:
@Component({
selector: 'app-signup',
standalone: true,
imports: [ReactiveFormsModule, RouterModule],
templateUrl: './signup.component.html',
styleUrl: './signup.component.css'
})
Next, inject the authentication and router services:
authService = inject(AuthService);
router = inject(Router);
Next, create the reactive form for signing up users:
public signupForm = new FormGroup({
name: new FormControl('', [Validators.required]),
email: new FormControl('', [Validators.required, Validators.email]),
password: new FormControl('', [Validators.required])
})
Finally, define the onSubmit()
method as follows:
public onSubmit() {
if (this.signupForm.valid) {
console.log(this.signupForm.value);
this.authService.signup(this.signupForm.value)
.subscribe({
next: (data: any) => {
console.log(data);
this.router.navigate(['/login']);
},
error: (err) => console.log(err)
});
}
}
Now open the src/app/pages/signup/signup.component.html
file and the HTML form for signup:
<div class="signup-card">
<div class="card-title">
<h1>Create Account</h1>
<span>Already have an account? <a routerLink="/login">Sign In</a></span>
</div>
<form class="form-group" [formGroup]="signupForm" (ngSubmit)="onSubmit()">
<input type="text" name="name" placeholder="Name" formControlName="name">
<input type="email" name="email" placeholder="Email" formControlName="email">
<input type="password" name="password" placeholder="Password" formControlName="password">
<input type="submit" value="Signup">
</form>
<div class="card-terms">
<input type="checkbox"> <span>I have read and agree to the <a href="">Terms of Service</a></span>
</div>
</div>
Open the src/app/pages/signup/signup.component.css
and style the signup page:
* {
box-sizing: border-box;
}
:host {
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: rgba(253, 101, 133, 1);
}
.signup-card {
border-radius: 10px;
box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.3);
width: 40%;
height: 450px;
background-color: #ffffff;
padding: 10px 30px;
}
.card-title {
padding: 10px;
}
.card-title h1 {
font-size: 26px;
font-weight: bold;
}
.form-group input {
margin: 5px 0;
width: 100%;
background-color: #e2e2e2;
border: none;
outline: none;
padding: 12px 20px;
border-radius: 4px;
}
.form-group input[type="submit"] {
background-color: #4796ff;
color: #ffffff;
font-size: 16px;
outline: none;
border-radius: 5px;
border: none;
padding: 8px 15px;
width: 100%;
}
.card-terms {
display: flex;
align-items: center;
padding: 10px;
}
.card-terms span {
margin: 5px;
font-size: 13px;
}
Implementing the Admin Page
Open the src/app/pages/admin/admin.component.ts
file and update it as follows:
import { Component, inject } from '@angular/core';
import { AuthService } from '../../auth/auth.service';
import { Router } from '@angular/router';
@Component({
selector: 'app-admin',
standalone: true,
imports: [],
templateUrl: './admin.component.html',
styleUrl: './admin.component.css'
})
export class AdminComponent {
authService = inject(AuthService);
router = inject(Router);
public logout(){
this.authService.logout();
this.router.navigate(['/login']);
}
}
Open the src/app/pages/admin/admin.component.html
file and update it as follows:
<button (click)="logout()">Logout</button>
Open the src/app/pages/admin/admin.component.css
file and update it as follows:
:host {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
background-color: rgba(253, 101, 133, 1);
}
button {
padding: 20px;
background-color: rgba(60, 10, 107, 0.562);
border-radius: 10px;
border: 0;
outline: none;
width: 300px;
}
Finally open the src/app/app.component.html
file and clear everything then add the router outlet:
<router-outlet></router-outlet>
Then open the src/styles.css
file and the following styles:
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@200;300;400;500;600;700&display=swap");
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Poppins", sans-serif;
}
Serve your app using the ng serve
command.
- Author: Ahmed Bouchefra Follow @ahmedbouchefra
-
Date:
Related posts
Login and Signup with API in Angular 17 Create Angular 17 Project Building a Password Strength Meter in Angular 17 Angular 17 Password Show/Hide with Eye Icon Angular 17 tutoriel Angular Select Change Event Angular iframe Angular FormArray setValue() and patchValue() Angular Find Substring in String Send File to API in Angular 17 EventEmitter Parent to Child Communication Create an Angular Material button with an icon and text Input change event in Angular 17 Find an element by ID in Angular 17 Find an element by ID from another component in Angular 17 Find duplicate objects in an array in JavaScript and Angular What is new with Angular 17 Style binding to text-decoration in Angular Remove an item from an array in Angular Remove a component in Angular Delete a component in Angular Use TypeScript enums in Angular templates Set the value of an individual reactive form fields Signal-based components in Angular 17 Angular libraries for Markdown: A comprehensive guide Angular libraries for cookies: A comprehensive guide Build an Angular 14 CRUD Example & Tutorial Angular 9 Components: Input and Output Angular 13 selectors Picture-in-Picture with JavaScript and Angular 10 Jasmine Unit Testing for Angular 12 Angular 9 Tutorial By Example: REST CRUD APIs & HTTP GET Requests with HttpClient Angular 10/9 Elements Tutorial by Example: Building Web Components Angular 10/9 Router Tutorial: Learn Routing & Navigation by Example Angular 10/9 Router CanActivate Guards and UrlTree Parsed Routes Angular 10/9 JWT Authentication Tutorial with Example Style Angular 10/9 Components with CSS and ngStyle/ngClass Directives Upload Images In TypeScript/Node & Angular 9/Ionic 5: Working with Imports, Decorators, Async/Await and FormData Angular 9/Ionic 5 Chat App: Unsubscribe from RxJS Subjects, OnDestroy/OnInit and ChangeDetectorRef Adding UI Guards, Auto-Scrolling, Auth State, Typing Indicators and File Attachments with FileReader to your Angular 9/Ionic 5 Chat App Private Chat Rooms in Angular 9/Ionic 5: Working with TypeScript Strings, Arrays, Promises, and RxJS Behavior/Replay Subjects Building a Chat App with TypeScript/Node.js, Ionic 5/Angular 9 & PubNub/Chatkit Chat Read Cursors with Angular 9/Ionic 5 Chat App: Working with TypeScript Variables/Methods & Textarea Keydown/Focusin Events Add JWT REST API Authentication to Your Node.js/TypeScript Backend with TypeORM and SQLite3 Database Building Chat App Frontend UI with JWT Auth Using Ionic 5/Angular 9 Install Angular 10 CLI with NPM and Create a New Example App with Routing Styling An Angular 10 Example App with Bootstrap 4 Navbar, Jumbotron, Tables, Forms and Cards Integrate Bootstrap 4/jQuery with Angular 10 and Styling the UI With Navbar and Table CSS Classes Angular 10/9 Tutorial and Example: Build your First Angular App Angular 9/8 ngIf Tutorial & Example Angular 10 New Features Create New Angular 9 Workspace and Application: Using Build and Serve Angular 10 Release Date: Angular 10 Will Focus on Ivy Artifacts and Libraries Support HTML5 Download Attribute with TypeScript and Angular 9 Angular 9.1+ Local Direction Query API: getLocaleDirection Example Angular 9.1 displayBlock CLI Component Generator Option by Example Angular 15 Basics Tutorial by Example Angular 9/8 ngFor Directive: Render Arrays with ngFor by Example Responsive Image Breakpoints Example with CDK's BreakpointObserver in Angular 9/8 Angular 9/8 DOM Queries: ViewChild and ViewChildren Example The Angular 9/8 Router: Route Parameters with Snapshot and ParamMap by Example Angular 9/8 Nested Routing and Child Routes by Example Angular 9 Examples: 2 Ways To Display A Component (Selector & Router) Angular 9/8 Tutorial: Http POST to Node/Express.js Example Angular 9/8 Feature and Root Modules by Example Angular 9/8 with PHP: Consuming a RESTful CRUD API with HttpClient and Forms Angular 9/8 with PHP and MySQL Database: REST CRUD Example & Tutorial Unit Testing Angular 9/8 Apps Tutorial with Jasmine & Karma by Example Angular 9 Web Components: Custom Elements & Shadow DOM Angular 9 Renderer2 with Directives Tutorial by Example Build Progressive Web Apps (PWA) with Angular 9/8 Tutorial and Example Angular 9 Internationalization/Localization with ngx-translate Tutorial and Example Create Angular 9 Calendar with ngx-bootstrap datepicker Example and Tutorial Multiple File Upload with Angular 9 FormData and PHP by Example Angular 9/8 Reactive Forms with Validation Tutorial by Example Angular 9/8 Template Forms Tutorial: Example Authentication Form (ngModel/ngForm/ngSubmit) Angular 9/8 JAMStack By Example Angular HttpClient v9/8 — Building a Service for Sending API Calls and Fetching Data Styling An Angular 9/8/7 Example App with Bootstrap 4 Navbar, Jumbotron, Tables, Forms and CardsHands-on Angular eBook
Subscribe to our Angular newsletter and get our hands-on Angular book for free!