Creating Login System in Angular and FastAPI

Rasyad
Rasyad
Dec 3, 2020 · 9 min read

In this tutorial we are going to build a simple login using Angular for the frontend application and FastAPI for the backend application.

Angular & FastAPI

To start things off, let’s first create our Angular app for the frontend. After we have finish creating the necessary thing in our frontend app, then only will we move to our backend.

Run below command. Make sure you have Node js installed.

With that, you will have you frontend application now running. But its the default application. We will have to create our own login component and services.

Default angular app

Open your project folder in the editor of your choice. I will be using Visual Studio.

Visual Studio

To make things simple, we would not be creating the layout component and other stuff, instead we only have to create two components, one for Login and another one for Profile, for when we have logged in.

In your command prompt, make sure you cd into your app folder.

You now have 2 newly created components in app/main folder with both in their respective folder.

Open you app-routing.module.ts and add the following.

const routes: Routes = [
{
path: 'login',
component: LoginComponent
},
{
path: 'profile',
component: ProfileComponent
},
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }

You should have something like this.

angular-routing

Go to your browser and try to go each route, /login and /profile.

At this point, both routes are accessible, but what we want is to have the profile component to only be accessible if the user is logged in.

Angular AuthGuard

To modify a page/route/component accessibility we can use AuthGuard.

First, let’s create a service for our AuthGuard class. Run the following.

And with that, you should have something like this.

angular auth-guard

Now, open up your AuthGuard and paste the following.

constructor(
private _authService: AuthService,
private _router: Router
) { }
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
if (this._authService.getToken()) {
return true;
}
// navigate to login page
this._router.navigate(['/login']);
// you can save redirect url so after authing we can move them back to the page they requested
return false;
}
}

You probably have already noticed that we do not have the AuthService class yet. Let’s go ahead and create that first.

Open up the auth-service.ts and paste the following.

Now, go back to your app-routing.module.ts and paste the following.

const routes: Routes = [

{ path: '', redirectTo: 'login', pathMatch: 'full' },
{
path: 'login',
component: LoginComponent
},
{
path: 'profile',
component: ProfileComponent,
canActivate:[AuthGuardService]
},
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }

Go to your browser and test out both routes, login and profile.

You will notice that upon trying to go to profile, you will get redirect to login page. If you still can go to profile, make sure there is no existing token in your browser local storage which you have set before.

Explanation

What we did in the above was creating two separate services, AuthGuard and Auth. The AuthGuard service is used to guard the route. How it works is that whenever a User tries to go to a route, the AuthGuard checks whether if the User has a token set in his/her browser.

If you open the Auth service, you can see we have 4 different methods that deal with the localStorage.

You might be asking when does the token get set then? Well, the token will get set after a successful login.

During a login, we will send the User’s username and password to the backend to check with the database, if it exists, we will send back a token to the frontend and the token will be set into the localStorage.

Not only that, after successful login, we can include the token in the request header every time we make an API call to a guarded endpoint.

Sounds cool? Lets code it.

Login Page

Let’s clean up our site looks a bit. Go to app.component.html and delete everything. Replace it with below.

I will not be styling the page though, I will leave that to you. Go crazy with your page’s look and style.

You should have something like this.

login page

Open your login.component.html and paste the following.

Open your login.component.ts and paste the following.

Make sure you import the ReactiveFormsModule and FormsModule in your app.module.ts or else you will get errors.

Test out your login now and upon submit you should a log in your console.

Now that the login box is working, the next part is making the API call to our backend.

Angular FastAPI : API Service

We will need to create 2 new services, one to make API calls and another one as an interceptor to modify our request header.

Run the following command.

Open your api.service and paste the following.

Notice that the REST_API_SERVER value is localhost:8000/. This value corresponds to our backend api.

The above code basically shows that we have 3 functions for each type of request we are going to make, the GET, POST and PUT.

Now open your interceptor-service and paste the following.

Open your app.module.ts and paste the following.

Make sure your components and the interceptor service are imported as well as the ReactiveFormsModule, FormsModule

Open your login.component.html and paste the following.

Now open your login.component.ts and paste the following.

You should have something like this.

login 2

For your profile.component.html, paste the following.

For your profile.component.ts, paste the following.

Upon successful login, you will be redirected to the profile page and the test_jwt() will automatically run to show you that the JWT is working and you can access the JWT protected endpoint.

It’s time to build our backend.

Angular FastAPI Backend

Let’s create our backend now. Make sure you have Python installed, I am using Anaconda but it works the same.

This will create a virtual env for your backend and also install FastAPI and uvicorrn.

Create a new file name main.py. Open it and paste the following.

To run your backend application, run the following.

Go to localhost:8000 to test it out.

fastapi backend

FastAPI Login Endpoint and JWT

First thing first, install the jwt.

Open your main.py and paste the following.

app = FastAPI()origins = [
"http://localhost",
"http://localhost:4200",
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
class User(BaseModel):
username: str
password: str
class Settings(BaseModel):
authjwt_secret_key: str = "my_jwt_secret"
@AuthJWT.load_config
def get_config():
return Settings()
@app.exception_handler(AuthJWTException)
def authjwt_exception_handler(request: Request, exc: AuthJWTException):
return JSONResponse(
status_code=exc.status_code,
content={"detail": exc.message}
)
@app.get("/")
def read_root():
return {"Hello": "World Rasyue"}
@app.post('/login')
def login(user: User, Authorize: AuthJWT = Depends()):
#user.username
#user.password
# this is the part where we will check the user credentials with our database record
#but since we are not going to use any db, straight away we will just create the token and send it back
# subject identifier for who this token is for example id or username from database
access_token = Authorize.create_access_token(subject=user.username)
return {"access_token": access_token}
@app.get('/test-jwt')
def user(Authorize: AuthJWT = Depends()):

Authorize.jwt_required()
return {"user": 123124124, 'data': 'jwt test works'}
#current_user = Authorize.get_jwt_subject()
#return {"user": current_user, 'data': 'jwt test works'}

And that is it for our backend. Remember to run with the command uvicorn main:app --reload

Now go back to your frontend and test the login system.

The End..

With that, we have successfully create a login system for our app using Angular for the frontend and FastAPI for the backend.

Stay tuned for more.

The Startup

Get smarter at building your thing. Join The Startup’s +786K followers.

Sign up for Top 10 Stories

By The Startup

Get smarter at building your thing. Subscribe to receive The Startup's top 10 most read stories — delivered straight into your inbox, once a week. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Rasyad

Written by

Rasyad

www.rasyue.com

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +786K followers.

Rasyad

Written by

Rasyad

www.rasyue.com

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +786K followers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store