@uib

Как реализовать Single sign-on?

Я хочу реализовать Single sign-on, но как сделать не совсем понимаю. На данный момент при запуске двух клиентов и одного сервера нужно авторизовываться на обоих клиентах, как можно сделать единый вход чтобы один раз авторизовался на любом из клиентов и на остальных авторизация уже не понадобилась. Сервер и клиенты имею одинаковые домены(localhost), а вот порт у всех разные.

token.interceptor.ts:

import { Injectable } from "@angular/core";
import { AuthService } from "../services/auth.service";
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse } from "@angular/common/http";
import { Observable, throwError } from "rxjs";
import { catchError } from "rxjs/operators";
import { Router } from "@angular/router";

@Injectable()
export class TokenInterceptor implements HttpInterceptor {
    constructor(private auth: AuthService, private router: Router){
    }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        if (this.auth.isAuthenticated()) {
            req = req.clone({
                setHeaders: {
                    Authorization: this.auth.getToken()
                }
            })
        }
        return next.handle(req).pipe(
            catchError(
                (error: HttpErrorResponse) => this.handleAuthError(error)
            )
        )
    }

    private handleAuthError(error: HttpErrorResponse): Observable<any> {
        if (error.status === 401) {
            this.router.navigate(['/login']), {
                queryParams: {
                    sessionFailed: true
                }
            }
        }

        return throwError(error)
    }

}

app.component.ts:

import { Component, OnInit } from '@angular/core';
import { AuthService } from './shared/services/auth.service';

@Component({
  selector: 'app-root',
  template: '<router-outlet></router-outlet>'
})
export class AppComponent implements OnInit {
  constructor(private auth: AuthService) {}

  ngOnInit() {
    const potentialToken = localStorage.getItem('auth-token')
    if (potentialToken !== null) {
      this.auth.setToken(potentialToken)
    }
  }
}

authService:

import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { Observable } from "rxjs";
import { tap } from "rxjs/operators";
import { User } from "../interfaces";

@Injectable({
    providedIn: 'root'
})
export class AuthService {

    private token = null;

    constructor(private http: HttpClient) {
    }

    login(user: User): Observable<{token: string}> {  
        return this.http.post<{token: string}>('/api/auth/login', user)
            .pipe(
                tap(
                    ({token}) => {
                        localStorage.setItem('auth-token', token)   
                        this.setToken(token)                     
                    }
                )
            )
    }

    setToken(token: string) {
        this.token = token
    }

    getToken(): string {
        return this.token
    }

    isAuthenticated(): boolean {
        return !!this.token
    }

    logout() {
        this.setToken(null) 
        localStorage.clear()

    }
}
  • Вопрос задан
  • 100 просмотров
Пригласить эксперта
Ответы на вопрос 1
inoise
@inoise
Solution Architect, AWS Certified, Serverless
Прочитайте про openID и JWT. Если вы хотите сделать Identity Server, то, пожалуйста, не мучайте себя и используйте готовые решения. Хотябы пресловутый Auth0
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы