diff --git a/.gitignore b/.gitignore
index 42b7fa639bc932b406003702ed1d80f18d7e4487..3c05752f8f36d3406e5337a9ab9ee62ab68074af 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,8 @@ yarn-error.log*
 
 .idea
 .vscode
+
+# keys and .env
+jwtRS256.key
+jwtRS256.key.pub
+server/.env
\ No newline at end of file
diff --git a/client/package-lock.json b/client/package-lock.json
index 5e65f7c6bad07adf6696b4b3e2464f63ef2c8924..6e9af44fc4954699b8c0d81bc6c309002639e693 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -15,6 +15,7 @@
         "@angular/platform-browser": "~11.1.1",
         "@angular/platform-browser-dynamic": "~11.1.1",
         "@angular/router": "~11.1.1",
+        "@auth0/angular-jwt": "^5.0.2",
         "rxjs": "~6.6.0",
         "tslib": "^2.0.0",
         "zone.js": "~0.11.3"
@@ -434,6 +435,17 @@
         "rxjs": "^6.5.3"
       }
     },
+    "node_modules/@auth0/angular-jwt": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/@auth0/angular-jwt/-/angular-jwt-5.0.2.tgz",
+      "integrity": "sha512-rSamC9mu+gUxoR86AXcIo+KD7xRIro+/iu1F2Ld85YAZEVKlpB5vYG+g0yGaEOqjtQWP/i0H6fi6XMGPVHSYYQ==",
+      "dependencies": {
+        "tslib": "^2.0.0"
+      },
+      "peerDependencies": {
+        "@angular/common": ">=9.0.0"
+      }
+    },
     "node_modules/@babel/code-frame": {
       "version": "7.12.13",
       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
@@ -19277,6 +19289,14 @@
         "tslib": "^2.0.0"
       }
     },
+    "@auth0/angular-jwt": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/@auth0/angular-jwt/-/angular-jwt-5.0.2.tgz",
+      "integrity": "sha512-rSamC9mu+gUxoR86AXcIo+KD7xRIro+/iu1F2Ld85YAZEVKlpB5vYG+g0yGaEOqjtQWP/i0H6fi6XMGPVHSYYQ==",
+      "requires": {
+        "tslib": "^2.0.0"
+      }
+    },
     "@babel/code-frame": {
       "version": "7.12.13",
       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
@@ -20926,13 +20946,15 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
       "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "ajv-keywords": {
       "version": "3.5.2",
       "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
       "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "alphanum-sort": {
       "version": "1.0.2",
@@ -21902,7 +21924,8 @@
       "version": "5.2.2",
       "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.2.tgz",
       "integrity": "sha512-g38K9Cm5WRwlaH6g03B9OEz/0qRizI+2I7n+Gz+L5DxXJAPAiWQvwlYNm1V1jkdpUv95bOe/ASm2vfi/G560jQ==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "class-utils": {
       "version": "0.3.6",
@@ -22090,13 +22113,15 @@
           "version": "9.0.0",
           "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-9.0.0.tgz",
           "integrity": "sha512-ctjwuntPfZZT2mNj2NDIVu51t9cvbhl/16epc5xEwyzyDt76pX9UgwvY+MbXrf/C/FWwdtmNtfP698BKI+9leQ==",
-          "dev": true
+          "dev": true,
+          "requires": {}
         },
         "@angular/core": {
           "version": "9.0.0",
           "resolved": "https://registry.npmjs.org/@angular/core/-/core-9.0.0.tgz",
           "integrity": "sha512-6Pxgsrf0qF9iFFqmIcWmjJGkkCaCm6V5QNnxMy2KloO3SDq6QuMVRbN9RtC8Urmo25LP+eZ6ZgYqFYpdD8Hd9w==",
-          "dev": true
+          "dev": true,
+          "requires": {}
         },
         "source-map": {
           "version": "0.5.7",
@@ -25216,7 +25241,8 @@
       "version": "5.1.0",
       "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
       "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "ieee754": {
       "version": "1.2.1",
@@ -26258,7 +26284,8 @@
       "version": "1.5.4",
       "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.5.4.tgz",
       "integrity": "sha512-PtilRLno5O6wH3lDihRnz0Ba8oSn0YUJqKjjux1peoYGwo0AQqrWRbdWk/RLzcGlb+onTyXAnHl6M+Hu3UxG/Q==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "karma-source-map-support": {
       "version": "1.4.0",
@@ -28738,7 +28765,8 @@
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
       "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "postcss-modules-local-by-default": {
       "version": "4.0.0",
@@ -34211,7 +34239,8 @@
       "version": "7.4.3",
       "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.3.tgz",
       "integrity": "sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "xml2js": {
       "version": "0.4.23",
diff --git a/client/package.json b/client/package.json
index edef3c6d9e8ef53b84e7ff11b7252978790eb2b6..805856fbe06a1a4fcb17a5f41ae89107924f9d83 100644
--- a/client/package.json
+++ b/client/package.json
@@ -19,6 +19,7 @@
     "@angular/platform-browser": "~11.1.1",
     "@angular/platform-browser-dynamic": "~11.1.1",
     "@angular/router": "~11.1.1",
+    "@auth0/angular-jwt": "^5.0.2",
     "rxjs": "~6.6.0",
     "tslib": "^2.0.0",
     "zone.js": "~0.11.3"
diff --git a/client/src/app/app.component.html b/client/src/app/app.component.html
index f883e04c2b54df54e15f9713c3c0f29e0ca5ba5c..6ad5852607b4366d9b3e425b23e6c75091c51fb8 100644
--- a/client/src/app/app.component.html
+++ b/client/src/app/app.component.html
@@ -12,4 +12,4 @@
 
 <div class="wrapper">
 	<router-outlet></router-outlet>
-</div>
+</div>
\ No newline at end of file
diff --git a/client/src/app/app.component.ts b/client/src/app/app.component.ts
index 6f97d4ed7d36e142c6cfd9a63f139cd068d6a94d..cc061ccd82009ac4a6add0a0df0b8e701e1c8d42 100644
--- a/client/src/app/app.component.ts
+++ b/client/src/app/app.component.ts
@@ -1,5 +1,4 @@
-import { Component
- } from '@angular/core';
+import { Component } from '@angular/core';
 
 @Component({
   selector: 'app-root',
@@ -7,5 +6,5 @@ import { Component
   styleUrls: ['./app.component.scss']
 })
 export class AppComponent {
-  title = 'client';
+  title: string = 'client';
 }
diff --git a/client/src/app/app.module.ts b/client/src/app/app.module.ts
index 28a13e79acd31f0b55aecb2588037c178e72002e..9b89086876c53bd68002c6c0fab318564f4e388b 100644
--- a/client/src/app/app.module.ts
+++ b/client/src/app/app.module.ts
@@ -1,13 +1,18 @@
 import { NgModule } from '@angular/core';
 import { BrowserModule } from '@angular/platform-browser';
 import { HttpClientModule } from '@angular/common/http';
+import { JwtModule } from "@auth0/angular-jwt";
 
 import { AppRoutingModule } from './app-routing.module';
 import { AppComponent } from './app.component';
 import { PostModule } from './posts/post.module';
 import { UserModule } from './users/user.module';
+import { AuthModule } from './authentication/auth.module';
 import { SharedModule } from './shared/shared.module';
 
+export function tokenGetter() {
+  return localStorage.getItem("token");
+}
 
 @NgModule({
   declarations: [
@@ -16,11 +21,18 @@ import { SharedModule } from './shared/shared.module';
   imports: [
     BrowserModule,
     UserModule,
-
+    AuthModule,
     AppRoutingModule,
     PostModule,
     SharedModule,
-    HttpClientModule
+    HttpClientModule,
+    JwtModule.forRoot({
+      config: {
+        tokenGetter: tokenGetter,
+        allowedDomains: ["localhost"],
+        disallowedRoutes: [""],
+      },
+    }),
   ],
   providers: [],
   bootstrap: [AppComponent]
diff --git a/client/src/app/authentication/auth.module.ts b/client/src/app/authentication/auth.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d2e4fae6f86c813833e6f24066c50b4076a0d599
--- /dev/null
+++ b/client/src/app/authentication/auth.module.ts
@@ -0,0 +1,12 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+
+
+@NgModule({
+  declarations: [],
+  imports: [
+    CommonModule
+  ]
+})
+export class AuthModule { }
diff --git a/client/src/app/authentication/auth.service.spec.ts b/client/src/app/authentication/auth.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3a8899d71403b14ef4e4854ceeca83f9a042afc7
--- /dev/null
+++ b/client/src/app/authentication/auth.service.spec.ts
@@ -0,0 +1,20 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { AuthService } from './auth.service';
+
+describe('AuthService', () => {
+  let service: AuthService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({
+      imports: [ HttpClientTestingModule, RouterTestingModule ]
+    });
+    service = TestBed.inject(AuthService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/client/src/app/authentication/auth.service.ts b/client/src/app/authentication/auth.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0d86deefb6903edb9943838c011c88d46e122c42
--- /dev/null
+++ b/client/src/app/authentication/auth.service.ts
@@ -0,0 +1,70 @@
+import { HttpClient, HttpEvent, HttpInterceptor, HttpResponse } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { User } from '../models/user.model';
+import { tap, shareReplay } from 'rxjs/operators';
+import { Router } from '@angular/router';
+
+interface IUserLogin {
+  username: string;
+  password: string;
+}
+
+@Injectable({
+  providedIn: 'root'
+})
+export class AuthService {
+  loginUrl = "api/user/login"
+
+  constructor(private http: HttpClient, private router: Router) { }
+
+  login(body: IUserLogin): Promise<string> {
+    return new Promise<string>(
+      (resolve, reject) => {
+        this.login_user(body).subscribe((data: any) => {
+          try {
+            resolve(data.token);
+          } catch (err: any) {
+            reject(err);
+          }
+        },
+        (err: any) => {
+          console.log(err.message);
+          reject(err);
+        });
+      }
+    );
+  }
+  private login_user(body: IUserLogin) {
+    return this.http.post(this.loginUrl, body).pipe(
+        tap(res =>this.setSession(res)),
+        shareReplay());;
+  }
+  private setSession(authResult) {
+    console.log(authResult);
+    localStorage.setItem('token', authResult.token);
+  }
+  checkTokenExpiration() {
+    const token = localStorage.getItem("token");
+    if (token) {
+      const {iat, exp} = JSON.parse(atob(token?.split(".")[1]));
+      if (iat && exp) {
+        const issued = new Date(iat*1000);
+        const expires = new Date(exp*1000);
+        const now = new Date();
+        // Expired token
+        if (now < issued || now >= expires) {
+          this.logout();
+          this.router.navigateByUrl("/");
+          return false
+        }
+        return true;
+      }
+    }
+    this.router.navigateByUrl("/")
+    return false
+  }
+  logout() {
+    localStorage.removeItem("token");
+  }
+
+}
diff --git a/client/src/app/users/user-login-form/user-login-form.component.spec.ts b/client/src/app/users/user-login-form/user-login-form.component.spec.ts
index 1e5bb79f2b6a8740c5ac7d47f366eb95a493a309..e680f03e5b6d7cfbb17b3ce59431f26a5fcd6e7c 100644
--- a/client/src/app/users/user-login-form/user-login-form.component.spec.ts
+++ b/client/src/app/users/user-login-form/user-login-form.component.spec.ts
@@ -1,4 +1,6 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
 
 import { UserLoginFormComponent } from './user-login-form.component';
 
@@ -8,7 +10,8 @@ describe('UserLoginFormComponent', () => {
 
   beforeEach(async () => {
     await TestBed.configureTestingModule({
-      declarations: [ UserLoginFormComponent ]
+      declarations: [ UserLoginFormComponent ],
+      imports: [ HttpClientTestingModule, RouterTestingModule ]
     })
     .compileComponents();
   });
diff --git a/client/src/app/users/user-login-form/user-login-form.component.ts b/client/src/app/users/user-login-form/user-login-form.component.ts
index 24057cbcefc53d9e5f0bb169537f82d8515b8006..328d380f561a08a0c64bf9cbc458acba399aef2a 100644
--- a/client/src/app/users/user-login-form/user-login-form.component.ts
+++ b/client/src/app/users/user-login-form/user-login-form.component.ts
@@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core';
 import { Router } from '@angular/router';
 import { User } from 'src/app/models/user.model';
 import { UserService } from '../user.service';
+import { AuthService } from '../../authentication/auth.service';
 
 @Component({
   selector: 'app-user-login-form',
@@ -14,7 +15,7 @@ export class UserLoginFormComponent implements OnInit {
 
   statusMessage: string = "";
 
-  constructor(private userService: UserService, private router: Router) { }
+  constructor(private userService: UserService, private authService: AuthService, private router: Router) { }
 
   ngOnInit(): void {
   }
@@ -46,13 +47,21 @@ export class UserLoginFormComponent implements OnInit {
         password: this.password,
       };
 
-      // Adds user to database and changes page afterwards
+      // Login the user
+      this.authService.login(request).then(status => {
+        console.log("User login1: " + JSON.stringify(status));
+        this.router.navigateByUrl("/");
+      }).catch(error => {
+        console.log("Error user login: " + error);
+      });
+      /* Old
       this.userService.login(request).then(status => {
-        console.log("User login: " + JSON.stringify(status));
+        console.log("User login2: " + JSON.stringify(status));
         this.router.navigateByUrl("/");
       }).catch(error => {
         console.log("Error adding user: " + error);
       });
+      */
     }
   }
 
diff --git a/client/src/app/users/user-profile/user-profile.component.html b/client/src/app/users/user-profile/user-profile.component.html
index fedcb8b611d8a4673ac53b4298a0877c86b35a42..9b8f3504202aab983a5623e14b3db63a95f90819 100644
--- a/client/src/app/users/user-profile/user-profile.component.html
+++ b/client/src/app/users/user-profile/user-profile.component.html
@@ -1 +1,4 @@
 <p>user-profile works!</p>
+<p>Userid: {{user.getUserId}}</p>
+<p>username: {{user.getUsername}}</p>
+<p>email: {{user.getEmail}}</p>
\ No newline at end of file
diff --git a/client/src/app/users/user-profile/user-profile.component.spec.ts b/client/src/app/users/user-profile/user-profile.component.spec.ts
index f0c36edb69f01b01f0236a8681070a3c8dce4027..4855ff37655c5f682abfbb90e35fed5219aa1484 100644
--- a/client/src/app/users/user-profile/user-profile.component.spec.ts
+++ b/client/src/app/users/user-profile/user-profile.component.spec.ts
@@ -1,4 +1,6 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
 
 import { UserProfileComponent } from './user-profile.component';
 
@@ -8,7 +10,8 @@ describe('UserProfileComponent', () => {
 
   beforeEach(async () => {
     await TestBed.configureTestingModule({
-      declarations: [ UserProfileComponent ]
+      declarations: [ UserProfileComponent ],
+      imports: [ HttpClientTestingModule, RouterTestingModule ]
     })
     .compileComponents();
   });
diff --git a/client/src/app/users/user-profile/user-profile.component.ts b/client/src/app/users/user-profile/user-profile.component.ts
index d7ff7744471c65e7b4e010e463f08f46b0f96d4a..53be4cceb4ffa0990d2be78603cd6f42361c75a3 100644
--- a/client/src/app/users/user-profile/user-profile.component.ts
+++ b/client/src/app/users/user-profile/user-profile.component.ts
@@ -1,4 +1,9 @@
 import { Component, OnInit } from '@angular/core';
+import { Router } from '@angular/router';
+import { AuthService } from 'src/app/authentication/auth.service';
+import { User } from 'src/app/models/user.model';
+import { UserService } from '../user.service';
+
 
 @Component({
   selector: 'app-user-profile',
@@ -7,9 +12,22 @@ import { Component, OnInit } from '@angular/core';
 })
 export class UserProfileComponent implements OnInit {
 
-  constructor() { }
+  user: User = new User();
+  constructor(private userService: UserService, private authService: AuthService, private router: Router) { }
 
   ngOnInit(): void {
+    // Check for token expiration
+    if (this.authService.checkTokenExpiration()) { // redirects to "/" if token is expired
+      const token = localStorage.getItem('token');
+      // Get user data from JWT token
+      const user_data = JSON.parse(atob(token.split(".")[1])).data[0];
+      // Gets all user information and displays them in the component
+      this.userService.getUser(user_data.userId).then(user => {
+        this.user = user;
+      }).catch (error => {
+        console.log("Error getting user: " + error);
+      });
+    }
+    
   }
-
 }
diff --git a/client/src/app/users/user-registration-form/user-registration-form.component.spec.ts b/client/src/app/users/user-registration-form/user-registration-form.component.spec.ts
index 142dcbf5fcb915aba5b1c810ba4afd43b6a71d8d..cc0d6286c96ad09899b00e8605843b3670043f26 100644
--- a/client/src/app/users/user-registration-form/user-registration-form.component.spec.ts
+++ b/client/src/app/users/user-registration-form/user-registration-form.component.spec.ts
@@ -1,4 +1,6 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
 
 import { UserRegistrationFormComponent } from './user-registration-form.component';
 
@@ -8,7 +10,8 @@ describe('UserRegistrationFormComponent', () => {
 
   beforeEach(async () => {
     await TestBed.configureTestingModule({
-      declarations: [ UserRegistrationFormComponent ]
+      declarations: [ UserRegistrationFormComponent ],
+      imports: [ HttpClientTestingModule, RouterTestingModule ]
     })
     .compileComponents();
   });
diff --git a/server/package-lock.json b/server/package-lock.json
index 4908b6d05a1f7ec91518bc06c6a6c292e579b4c4..505bf96189764d4512ec8d93a833b7e99311ab72 100644
--- a/server/package-lock.json
+++ b/server/package-lock.json
@@ -10,19 +10,24 @@
       "dependencies": {
         "@types/cors": "^2.8.9",
         "@types/express": "^4.17.11",
+        "@types/express-jwt": "^6.0.1",
         "@types/jest": "^26.0.20",
         "@types/mysql": "^2.15.17",
         "@types/supertest": "^2.0.10",
         "body-parser": "^1.19.0",
         "cors": "^2.8.5",
+        "dotenv": "^8.2.0",
         "express": "^4.17.1",
+        "express-jwt": "^6.0.0",
         "jest": "^26.6.3",
+        "jsonwebtoken": "^8.5.1",
         "mysql": "^2.18.1",
         "mysql2": "^2.2.5",
         "supertest": "^6.1.3",
         "ts-jest": "^26.5.1"
       },
       "devDependencies": {
+        "@types/jsonwebtoken": "^8.5.0",
         "nodemon": "^2.0.7",
         "ts-node": "^9.1.1",
         "typescript": "^4.1.3"
@@ -1014,6 +1019,15 @@
         "@types/serve-static": "*"
       }
     },
+    "node_modules/@types/express-jwt": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@types/express-jwt/-/express-jwt-6.0.1.tgz",
+      "integrity": "sha512-zB/oXzS8/NTWUzAG343frlqUrsygHPeyYMVcbJ8YYk7rF1G15eUapPgWh0HdeFi51ajFkkUOU+Q540z1Eu4hJQ==",
+      "dependencies": {
+        "@types/express": "*",
+        "@types/express-unless": "*"
+      }
+    },
     "node_modules/@types/express-serve-static-core": {
       "version": "4.17.18",
       "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.18.tgz",
@@ -1024,6 +1038,14 @@
         "@types/range-parser": "*"
       }
     },
+    "node_modules/@types/express-unless": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.5.1.tgz",
+      "integrity": "sha512-5fuvg7C69lemNgl0+v+CUxDYWVPSfXHhJPst4yTLcqi4zKJpORCxnDrnnilk3k0DTq/WrAUdvXFs01+vUqUZHw==",
+      "dependencies": {
+        "@types/express": "*"
+      }
+    },
     "node_modules/@types/graceful-fs": {
       "version": "4.1.5",
       "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz",
@@ -1062,6 +1084,15 @@
         "pretty-format": "^26.0.0"
       }
     },
+    "node_modules/@types/jsonwebtoken": {
+      "version": "8.5.0",
+      "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.0.tgz",
+      "integrity": "sha512-9bVao7LvyorRGZCw0VmH/dr7Og+NdjYSsKAxB43OQoComFbBgsEpoR9JW6+qSq/ogwVBg8GI2MfAlk4SYI4OLg==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
     "node_modules/@types/mime": {
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
@@ -1403,6 +1434,11 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/async": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
+    },
     "node_modules/asynckit": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -1697,6 +1733,11 @@
         "node-int64": "^0.4.0"
       }
     },
+    "node_modules/buffer-equal-constant-time": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+      "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
+    },
     "node_modules/buffer-from": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
@@ -2387,6 +2428,14 @@
         "node": ">=8"
       }
     },
+    "node_modules/dotenv": {
+      "version": "8.2.0",
+      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
+      "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/duplexer3": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
@@ -2402,6 +2451,14 @@
         "safer-buffer": "^2.1.0"
       }
     },
+    "node_modules/ecdsa-sig-formatter": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+      "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
     "node_modules/ee-first": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -2744,6 +2801,25 @@
         "node": ">= 0.10.0"
       }
     },
+    "node_modules/express-jwt": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/express-jwt/-/express-jwt-6.0.0.tgz",
+      "integrity": "sha512-C26y9myRjx7CyhZ+BAT3p+gQyRCoDZ7qo8plCvLDaRT6je6ALIAQknT6XLVQGFKwIy/Ux7lvM2MNap5dt0T7gA==",
+      "dependencies": {
+        "async": "^1.5.0",
+        "express-unless": "^0.3.0",
+        "jsonwebtoken": "^8.1.0",
+        "lodash.set": "^4.0.0"
+      },
+      "engines": {
+        "node": ">= 8.0.0"
+      }
+    },
+    "node_modules/express-unless": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/express-unless/-/express-unless-0.3.1.tgz",
+      "integrity": "sha1-JVfBRudb65A+LSR/m1ugFFJpbiA="
+    },
     "node_modules/extend": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@@ -4904,6 +4980,32 @@
         "node": ">=6"
       }
     },
+    "node_modules/jsonwebtoken": {
+      "version": "8.5.1",
+      "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
+      "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
+      "dependencies": {
+        "jws": "^3.2.2",
+        "lodash.includes": "^4.3.0",
+        "lodash.isboolean": "^3.0.3",
+        "lodash.isinteger": "^4.0.4",
+        "lodash.isnumber": "^3.0.3",
+        "lodash.isplainobject": "^4.0.6",
+        "lodash.isstring": "^4.0.1",
+        "lodash.once": "^4.0.0",
+        "ms": "^2.1.1",
+        "semver": "^5.6.0"
+      },
+      "engines": {
+        "node": ">=4",
+        "npm": ">=1.4.28"
+      }
+    },
+    "node_modules/jsonwebtoken/node_modules/ms": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+    },
     "node_modules/jsprim": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@@ -4918,6 +5020,25 @@
         "verror": "1.10.0"
       }
     },
+    "node_modules/jwa": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
+      "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
+      "dependencies": {
+        "buffer-equal-constant-time": "1.0.1",
+        "ecdsa-sig-formatter": "1.0.11",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/jws": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
+      "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+      "dependencies": {
+        "jwa": "^1.4.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
     "node_modules/keyv": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
@@ -4996,6 +5117,46 @@
       "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
       "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
     },
+    "node_modules/lodash.includes": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
+      "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8="
+    },
+    "node_modules/lodash.isboolean": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+      "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY="
+    },
+    "node_modules/lodash.isinteger": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+      "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M="
+    },
+    "node_modules/lodash.isnumber": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+      "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w="
+    },
+    "node_modules/lodash.isplainobject": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+      "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
+    },
+    "node_modules/lodash.isstring": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+      "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE="
+    },
+    "node_modules/lodash.once": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+      "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
+    },
+    "node_modules/lodash.set": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz",
+      "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM="
+    },
     "node_modules/lodash.sortby": {
       "version": "4.7.0",
       "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
@@ -8949,6 +9110,15 @@
         "@types/serve-static": "*"
       }
     },
+    "@types/express-jwt": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@types/express-jwt/-/express-jwt-6.0.1.tgz",
+      "integrity": "sha512-zB/oXzS8/NTWUzAG343frlqUrsygHPeyYMVcbJ8YYk7rF1G15eUapPgWh0HdeFi51ajFkkUOU+Q540z1Eu4hJQ==",
+      "requires": {
+        "@types/express": "*",
+        "@types/express-unless": "*"
+      }
+    },
     "@types/express-serve-static-core": {
       "version": "4.17.18",
       "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.18.tgz",
@@ -8959,6 +9129,14 @@
         "@types/range-parser": "*"
       }
     },
+    "@types/express-unless": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.5.1.tgz",
+      "integrity": "sha512-5fuvg7C69lemNgl0+v+CUxDYWVPSfXHhJPst4yTLcqi4zKJpORCxnDrnnilk3k0DTq/WrAUdvXFs01+vUqUZHw==",
+      "requires": {
+        "@types/express": "*"
+      }
+    },
     "@types/graceful-fs": {
       "version": "4.1.5",
       "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz",
@@ -8997,6 +9175,15 @@
         "pretty-format": "^26.0.0"
       }
     },
+    "@types/jsonwebtoken": {
+      "version": "8.5.0",
+      "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.0.tgz",
+      "integrity": "sha512-9bVao7LvyorRGZCw0VmH/dr7Og+NdjYSsKAxB43OQoComFbBgsEpoR9JW6+qSq/ogwVBg8GI2MfAlk4SYI4OLg==",
+      "dev": true,
+      "requires": {
+        "@types/node": "*"
+      }
+    },
     "@types/mime": {
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
@@ -9272,6 +9459,11 @@
       "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
       "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
     },
+    "async": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
+    },
     "asynckit": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -9501,6 +9693,11 @@
         "node-int64": "^0.4.0"
       }
     },
+    "buffer-equal-constant-time": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+      "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
+    },
     "buffer-from": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
@@ -10039,6 +10236,11 @@
         "is-obj": "^2.0.0"
       }
     },
+    "dotenv": {
+      "version": "8.2.0",
+      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
+      "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw=="
+    },
     "duplexer3": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
@@ -10054,6 +10256,14 @@
         "safer-buffer": "^2.1.0"
       }
     },
+    "ecdsa-sig-formatter": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+      "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+      "requires": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
     "ee-first": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -10312,6 +10522,22 @@
         "vary": "~1.1.2"
       }
     },
+    "express-jwt": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/express-jwt/-/express-jwt-6.0.0.tgz",
+      "integrity": "sha512-C26y9myRjx7CyhZ+BAT3p+gQyRCoDZ7qo8plCvLDaRT6je6ALIAQknT6XLVQGFKwIy/Ux7lvM2MNap5dt0T7gA==",
+      "requires": {
+        "async": "^1.5.0",
+        "express-unless": "^0.3.0",
+        "jsonwebtoken": "^8.1.0",
+        "lodash.set": "^4.0.0"
+      }
+    },
+    "express-unless": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/express-unless/-/express-unless-0.3.1.tgz",
+      "integrity": "sha1-JVfBRudb65A+LSR/m1ugFFJpbiA="
+    },
     "extend": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@@ -11928,6 +12154,30 @@
         "minimist": "^1.2.5"
       }
     },
+    "jsonwebtoken": {
+      "version": "8.5.1",
+      "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
+      "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
+      "requires": {
+        "jws": "^3.2.2",
+        "lodash.includes": "^4.3.0",
+        "lodash.isboolean": "^3.0.3",
+        "lodash.isinteger": "^4.0.4",
+        "lodash.isnumber": "^3.0.3",
+        "lodash.isplainobject": "^4.0.6",
+        "lodash.isstring": "^4.0.1",
+        "lodash.once": "^4.0.0",
+        "ms": "^2.1.1",
+        "semver": "^5.6.0"
+      },
+      "dependencies": {
+        "ms": {
+          "version": "2.1.3",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+          "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+        }
+      }
+    },
     "jsprim": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@@ -11939,6 +12189,25 @@
         "verror": "1.10.0"
       }
     },
+    "jwa": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
+      "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
+      "requires": {
+        "buffer-equal-constant-time": "1.0.1",
+        "ecdsa-sig-formatter": "1.0.11",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "jws": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
+      "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+      "requires": {
+        "jwa": "^1.4.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
     "keyv": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
@@ -11999,6 +12268,46 @@
       "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
       "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
     },
+    "lodash.includes": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
+      "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8="
+    },
+    "lodash.isboolean": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+      "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY="
+    },
+    "lodash.isinteger": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+      "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M="
+    },
+    "lodash.isnumber": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+      "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w="
+    },
+    "lodash.isplainobject": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+      "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
+    },
+    "lodash.isstring": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+      "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE="
+    },
+    "lodash.once": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+      "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
+    },
+    "lodash.set": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz",
+      "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM="
+    },
     "lodash.sortby": {
       "version": "4.7.0",
       "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
diff --git a/server/package.json b/server/package.json
index ddee43554ba1ad65283c4c99422e5e6a4cc92e65..96d322e6f3a95aa83ad006b1200ff298c9ba84f4 100644
--- a/server/package.json
+++ b/server/package.json
@@ -12,19 +12,24 @@
   "dependencies": {
     "@types/cors": "^2.8.9",
     "@types/express": "^4.17.11",
+    "@types/express-jwt": "^6.0.1",
     "@types/jest": "^26.0.20",
     "@types/mysql": "^2.15.17",
     "@types/supertest": "^2.0.10",
     "body-parser": "^1.19.0",
     "cors": "^2.8.5",
+    "dotenv": "^8.2.0",
     "express": "^4.17.1",
+    "express-jwt": "^6.0.0",
     "jest": "^26.6.3",
+    "jsonwebtoken": "^8.5.1",
     "mysql": "^2.18.1",
     "mysql2": "^2.2.5",
     "supertest": "^6.1.3",
     "ts-jest": "^26.5.1"
   },
   "devDependencies": {
+    "@types/jsonwebtoken": "^8.5.0",
     "nodemon": "^2.0.7",
     "ts-node": "^9.1.1",
     "typescript": "^4.1.3"
diff --git a/server/src/config.ts b/server/src/config.ts
index 3ca155ce5e0713f7de4897f7776f914f47815bd8..f2dc97f88fcb1a73d5db5ac435bb2c5d720eb9b0 100644
--- a/server/src/config.ts
+++ b/server/src/config.ts
@@ -1,6 +1,8 @@
+const { config } = require('dotenv');
+config({ path: __dirname+'/../.env'});
 const env = process.env;
 
-const config = {
+export default {
 	db: {
 		host: env.DB_HOST || 'mysql.stud.ntnu.no',
 		user: env.DB_USER || 'jonnynl_tdt4140',
@@ -12,6 +14,9 @@ const config = {
 		debug: false
 	},
 	listPerPage: 10,
+	JWT_KEY : env.JWT_KEY || "",
+	HOST: env.HOST || "localhost",
+    PORT: env.HTTPPORT || 3000,
+    ACCESS_TOKEN_SECRET: env.ACCESS_TOKEN_SECRET,
+    REFRESH_TOKEN_SECRET: env.REFRESH_TOKEN_SECRET,
 };
-
-export default config;
diff --git a/server/src/controllers/userController/index.ts b/server/src/controllers/userController/index.ts
index f45e65b84e04f91af4dc713afb020471ef2d36ef..33b925ac4f38ca3feff091493942608d0a840a14 100644
--- a/server/src/controllers/userController/index.ts
+++ b/server/src/controllers/userController/index.ts
@@ -2,6 +2,9 @@ import { Response, Request } from "express";
 import query from '../../services/db_query';
 import express from 'express';
 import IUser from '../../models/user';
+import * as jwt from 'jsonwebtoken';
+import config from '../../config';
+import authenticateToken from '../../middlewares/auth';
 
 const router = express.Router();
 /* ============================= CREATE ============================= */
@@ -35,7 +38,7 @@ router.route('/').get(async (_: Request, response: Response) => {
 });
 
 // Get user with id `/api/user/:id`
-router.route('/:userId').get(async (request: Request, response: Response) => {
+router.route('/:userId').get(authenticateToken, async (request: Request, response: Response) => {
 	const userId = request.params.userId;
 	try {
 		const input = `SELECT userId, username, email, create_time FROM user WHERE userId=?;`
@@ -50,9 +53,23 @@ router.route('/login').post(async (request: Request, response: Response) => {
 	const {username, password} = request.body;
 	try {
 		const input = "SELECT userId, username, email, create_time FROM user WHERE username=? AND password=?;"
-		response.status(200).json(await query(input,[username, password]));
+		const user = await query(input,[username, password]);
+		// Check if an user object is retrieved
+		const userObj = Object.values(JSON.parse(JSON.stringify(user.data)))[0];
+		if (userObj) {
+			const jwt_token = jwt.sign({data: user.data}, config.JWT_KEY.replace(/\\n/gm, '\n'), {
+				algorithm: 'RS256',
+				expiresIn: 3600*24, // 24 hours
+			});
+			response.status(200).json({
+				token: jwt_token,
+			});
+		} else {
+			response.status(403).send("Invalid combination of username and password given!");
+		}
 	} catch (error) {
 		response.status(400).send("Bad Request");
+		console.log(error);
 	}
 });
 
diff --git a/server/src/index.ts b/server/src/index.ts
index d4b49774f337ac7b92acab230b4e8fe2970b442e..77bda9f8885ca4745be8d40879d505b3fb2fe492 100644
--- a/server/src/index.ts
+++ b/server/src/index.ts
@@ -1,8 +1,10 @@
 import app from './app';
+import config from './config';
 
 // REST API config
-const port = 3000;
+const port = config.PORT;
 
 app.listen(port, () => {
-	console.log(`Listening on port ${port}!`)
+	const host = config.HOST;
+	console.log('[*] Server listening at http://%s:%s \n', host, port);
 });
\ No newline at end of file
diff --git a/server/src/middlewares/auth.ts b/server/src/middlewares/auth.ts
new file mode 100644
index 0000000000000000000000000000000000000000..023f2683204a0daced88b4c4fc6b9ebfcdf6beeb
--- /dev/null
+++ b/server/src/middlewares/auth.ts
@@ -0,0 +1,10 @@
+import expressJwt from 'express-jwt';
+import config from '../config';
+
+const JWT_KEY = config.JWT_KEY.replace(/\\n/gm, '\n');
+
+const authenticateToken = expressJwt({
+    algorithms: ['RS256'],
+    secret: JWT_KEY,
+});
+export default authenticateToken;
\ No newline at end of file