I have a question regarding how to password protect a web page. I used angular material to create a webpage that will talk to back-end service to query information. I also add an admin sub-page to do website configuration.
I'd like to make the admin page protected by password. This protection can be a very simple security feature, nothing complicated is required. Just a token that only a few people knows, once they enter the valid token the admin page will show.
I looked a few ways:
- .htaccess and .htpassword
- embed a java script as header in admin.component.html
- angular router link authentication
1 and 2 do not work for me 3 seems to be an overkill for my requirement.
Any idea how to make a simple password protected webpage? Also if I have to go with 3, it will protect any page re-routed to admin page. However if I directly enter www.mysite.com/admin, will it still be protected?
CodePudding user response:
I would use auth guards.
Try to look at users: https://angular-authguard-jwt-duxyen.stackblitz.io/users
You can't, it's guarded until you log in.
We have set an authGuard on our users route.
const routes: Routes = [
{ path: 'users', component: UsersComponent, canActivate: [AuthGuard] }
];
This is what authorizes what's visible and what is not.
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private _authService: AuthService, private router: Router){}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
if(this._authService.loggedIn()){
return true;
}else{
this.router.navigate(['/login']);
return false;
}
}
}
Auth service returns the token for canActivate
when asked for.
@Injectable()
export class AuthService {
constructor() { }
loggedIn(){
return !!localStorage.getItem('token');
}
getToken(){
return localStorage.getItem('token');
}
}
We use store a token to localStorage to keep track if user is authenticated to access our /users
route.
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css'],
})
export class LoginComponent implements OnInit {
loginUserData: User = { username: '', password: '' };
allowedUsername = 'Mike';
allowedPassword = '123';
constructor(private _auth: AuthService, private router: Router) {}
ngOnInit() {}
loginUser() {
if (
this.loginUserData.username == this.allowedUsername &&
this.loginUserData.password == this.allowedPassword
) {
console.log('login success');
localStorage.setItem('token', 'scretToken');
localStorage.setItem('is_admin', 'true');
this.router.navigate(['/home']);
}
}
}
export interface User {
username: string;
password: string;
}
Using a token is quite common client side authentication. In our case, the token is hard-coded but if you want to expand this to an actual authentication process you could. I removed it for simplicity (hint: google JWT token if you're interested).
Basically after login, we put a key/value pair on clients localStorage. key
is token and it's value
is "scretToken". We put it there once user successfully logs in for the first time. We then redirect user to /users
url. On arriving to /users
our authGuard
kicks in, checking if client has token "scretToken" on their machine. If they have they can see the contents. If not, their tossed back to /login
.
Because we're storing token in localStorage, even if user refreshes or changes tab, their still authenticated. If they clear their browsing data manually the token is removed. If they logout with our logout button, we also delete the token from localStorage.
Log in here: https://angular-authguard-jwt-duxyen.stackblitz.io/login
Username: Mike
, Password: 123
Working example: https://stackblitz.com/edit/angular-authguard-jwt-duxyen?file=src/app/login/login.component.ts