Once user sign up, we store the user data inside cookie in the broswer and also keep a memory copy in the server.
If next time, user refresh the page, we want to tell that the user is already authed.
Create a endpoint, to retrive the user data:
app.route('/api/user') .get(getUser);
Router:
import {Request, Response} from 'express';import {sessionStore} from './session-store';export function getUser(req: Request, res: Response) { // Get sessionid from cookies const sessionId = req.cookies['SESSIONID']; // get user according to the session id from the session storage const user = sessionStore.findUserBySessionId(sessionId); if (user) { // if there is user, send successful response res.status(200).json(user); } else { // if there is no user, send empty response res.sendStatus(204); }}
SessionStorage:
import {Session} from './session';import {User} from '../src/app/model/user';class SessionStore { private sessions: {[key: string]: Session} = {}; createSession(sessionId: string, user: User) { this.sessions[sessionId] = new Session(sessionId, user); } findUserBySessionId(sessionId: string): User | undefined { const session = this.sessions[sessionId]; const isSessionValid = session && session.isValid(); return isSessionValid ? session.user : undefined; }}// We want only global singletonexport const sessionStore = new SessionStore();
On the client, once page loaded, we try to get user data first.
import { Injectable } from '@angular/core';import {HttpClient} from '@angular/common/http';import {Observable} from 'rxjs/Observable';import {User} from '../model/user';import {BehaviorSubject} from 'rxjs/BehaviorSubject';import 'rxjs/add/operator/map';import 'rxjs/add/operator/shareReplay';import 'rxjs/add/operator/filter';import 'rxjs/add/operator/do';export const ANONYMOUS_USER: User = { id: undefined, email: ''};@Injectable()export class AuthService { subject = new BehaviorSubject(undefined); // filter out undefined user user$: Observable = this.subject.asObservable().filter(user => !!user); isLoggedIn$: Observable = this.user$.map(user => !!user.id); isLoggedOut$: Observable = this.isLoggedIn$.map(isLoggedIn => !isLoggedIn); constructor(private http: HttpClient) { this.http.get ('/api/user') // when there is valid session id, emit the user$ .subscribe((user) => this.subject.next(user ? user : ANONYMOUS_USER)); } signUp(email: string, password: string) { return this.http.post ('/api/signup', { email, password }).shareReplay() .do((user) => this.subject.next(user)); }}