如何保证一个系统只有一个用户可以登录(api.service.ts、app.config.ts)

1.每次登录,用refresh_token,更新该用户名的token

保证最近一次所登录用户的token最新

  login() {let fontSize = localStorage.getItem("fontSize")this.userServ.login(this.username, this.password).toPromise().then(() => {this.userServ.updateToken().subscribe(token => {this.userServ.getRolesByUsername(this.username).subscribe(info => {if (info.length == 0) {this.message.error("系统不存在此用户名!");return}if (info[0].name.match("ROLE_CEMSS")) {this.http.get('assets/sysconfig/sysconfig.json').subscribe((data: SysConfig) => {this.userServ.getUserInfo(this.username).toPromise().then(userinfo => {this.message.loading("登录成功,正在跳转...")localStorage.setItem("fontSize", fontSize ? fontSize : data.font_size);// console.log(userinfo);this.areaServ.getByKey(userinfo.areaCode).then(area => {// console.log(area);if (area.cCode == 100000) {this.apiServ.title = "国家级生态气象业务云平台"} else {this.apiServ.title = `${area.cName}生态气象业务云系统`;}this.apiServ.areaCode = userinfo.areaCode;this.message.remove();this.message.success("登录成功");this.refreshLoginStatus();//按用户不同角色权限 分配菜单this.getPowerMenu();})})})} else {this.message.error("系统不存在此用户名!");}}, e => {this.message.error("系统验证用户失败!");})}, (err) => {this.message.error("更新Token失败:" + JSON.stringify(err));})}).catch((err) => {this.message.error("登录失败:" + JSON.stringify(err));this.refreshLoginStatus();});}

2.设置定时器,定时检验token

登录时,保存token、refresh_token到sessionStorage.

 //两个用户不能同时使用同一账号登录let interval = setInterval(() => {if (this.apiServ.token == null) {clearInterval(interval);this.router.navigate(['/welcome']);} else {//非退出登录 且 token未过期 this.userServ.checkToken().subscribe(data => { }, (error) => {clearInterval(interval);this.modalService.closeAll();//关闭弹框this.message.error('登录失效!!!')this.apiServ.clearToken();this.router.navigate(['/welcome']);})}}, 60000)

3.若token失效,取消定时器、退出登录

user.service.ts

import { Injectable } from '@angular/core';
import { ApiService } from './api.service';
import { HttpClient, HttpParams } from '@angular/common/http';
import { AppConfig } from './app.config';
import { Token } from '../model/token';
import { Observable } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { CacheService } from './cache.service';
import { ErrorHandler } from '../model/error-handler';@Injectable()
export class UserService extends ApiService {private url: string;private pwd: string;constructor(http: HttpClient, private appConfig: AppConfig, private cacheService: CacheService, private errorHandler: ErrorHandler) {super(http);this.url = this.appConfig.sysConfig.user_url;}public login(username: string, password: string): Observable<Token> {let url = this.url + '/oauth/token?grant_type=password&username=' + username + '&password=' + password;let options = {headers: {'Content-Type': 'application/x-www-form-urlencoded','Authorization': 'Basic ' + 'eXotc2VydmljZS1jbGllbnQ6YWdtczEyMzQ='}};return this.http.post<Token>(url, null, options).pipe(map((token: Token) => {this.setToken(token, username);sessionStorage.setItem("token", token.access_token);this.cacheService.cache();return token;}));}public updateToken(): Observable<Token> {let url = this.url + '/oauth/token?grant_type=refresh_token&refresh_token=' + this.refresh_token;let options = {headers: {'Content-Type': 'application/x-www-form-urlencoded','Authorization': 'Basic ' + 'eXotc2VydmljZS1jbGllbnQ6YWdtczEyMzQ='}};return this.http.post<Token>(url, null, options).pipe(map((token: Token) => {sessionStorage.setItem("token", token.access_token);this.cacheService.cache();return token}));}public checkToken() {let url = this.url + '/oauth/check_token?token=' + this.token;let options = { headers: super.jwt() };return this.http.get<any>(url, options).pipe(map((data) => {return data})).pipe(catchError(this.errorHandler.handleError));}public getUserInfo(username: string) {let url = this.url + '/oauth/users/info';let params: HttpParams = new HttpParams()params = params.set('username', username);let options = { headers: super.jwt(), params: params };return this.http.get<any>(url, options).pipe(map(userinfo => userinfo));}//按用户不同角色权限 分配菜单public getUserMenu(systemName: string, userName: string): Observable<Array<PowerMenu>> {let url = this.url + '/oauth/users/user/menus';let params: HttpParams = new HttpParams()params = params.set('systemName', systemName);params = params.set('userName', userName);let options = { headers: super.jwt(), params: params };return this.http.get<Array<PowerMenu>>(url, options).pipe(map((powerMenu: Array<PowerMenu>) => powerMenu));}getRolesByUsername(username: string) {let url = this.url + '/oauth/roles/username/' + username;return this.http.get(url, { headers: super.jwt() }).pipe(map((nameInfo: Array<any>) => {return nameInfo;}))}
}export class PowerMenu {id: number;systemId: number;leaf: boolean;parentId: number;name: string;cname: string;children: Array<PowerMenu>;permissions: {id: number;name: string;permissionUrl: string;method: string,description: string}[];
}

api.service.ts

import { Injectable, APP_INITIALIZER } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { AppConfig, SysConfig } from './app.config';
import { Token } from '../model/token';@Injectable({ providedIn: 'root' })
export class ApiService {public set areaCode(areaCode: number) {sessionStorage.setItem("areaCode", areaCode.toString());}public get areaCode(): number {return Number(sessionStorage.getItem("areaCode"));}public setToken(token: Token, username: string) {sessionStorage.setItem("token", token.access_token);sessionStorage.setItem("login_time", new Date().getTime().toString());sessionStorage.setItem("expires_in", token.expires_in.toString());sessionStorage.setItem("username", username);sessionStorage.setItem("refresh_token", token.refresh_token);}public get refresh_token(): string {return sessionStorage.getItem("refresh_token");}public get token(): string {return sessionStorage.getItem("token");}private get expires_in(): number {return Number(sessionStorage.getItem("expires_in"));}private get login_time(): string {return sessionStorage.getItem("login_time");}public get username(): string {return sessionStorage.getItem("username");// return "scsqxzhfyjszx";// return "neimeng";}public clearToken(): void {sessionStorage.removeItem("token");sessionStorage.removeItem("login_time");sessionStorage.removeItem("expires_in");sessionStorage.removeItem("username");sessionStorage.removeItem("areaCode");sessionStorage.removeItem("refresh_token");}public set title(title: string) {sessionStorage.setItem("title", title);}public get title(): string {return sessionStorage.getItem("title");}// true为过期 留出10秒空余量public get isTokenExpires(): boolean {let time = new Date().getTime() - Number(this.login_time);return time > (this.expires_in - 10) * 1000;}constructor(protected http: HttpClient) {}public getWebUrl() {let host = window.location.hostname || '127.0.0.1';let port = window.location.port || 81;return 'http://' + host + ':' + port;}public jwt(): HttpHeaders {if (this.token) {return new HttpHeaders().set("Authorization", 'Bearer ' + this.token);}return null;}}

app.config.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';const jsonFile = 'assets/sysconfig/sysconfig.json';
@Injectable()
export class AppConfig {private _sysConfig: SysConfig;constructor(private http: HttpClient) { }load() {return new Promise<void>((resolve, reject) => {this.http.get(jsonFile).toPromise().then((data: SysConfig) => {this._sysConfig = data;resolve();}).catch((response: any) => {reject(`load sysConfig file '${jsonFile}' error`);});});}get sysConfig(): SysConfig {return this._sysConfig;}
}export class SysConfig {map_url: string;product_url: string;gis_url: string;meta_url: string;user_url: string;task_url: string;cemss_url: string;cemss_ws_url: string;font_size: string;
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部