【问题标题】:How to handle User Session in angular 5如何在角度 5 中处理用户会话
【发布时间】:2020-02-10 21:24:37
【问题描述】:

对于后端,我使用带有“Shiro”的 Spring Framework 进行身份验证,

对于前端,我使用的是 Angular 5。

如果我从邮递员那里调用我的登录 API,那么在我使用注销 API 之前,我将获得相同的用户会话。 (哪个是正确的)

邮递员界面图片:

但是当我从我的 Angular 5 调用我的登录 API 时,每次调用都会得到不同的用户会话。 (这是错误的。)

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import 'rxjs/add/operator/toPromise';

@Injectable()
export class LoginService {
  private headers = new Headers({'Content-Type': 'application/x-www-form-urlencoded'});
  private _url:string = "v1/login";

  constructor(private http: HttpClient) { }

  login(){
    const data = {userName:"root", password:"root"};
    return this.http.post(this._url,{headers: this.headers},{params : data})
    .subscribe(data => {sessionStorage.setItem("jsessionid",JSON.parse(JSON.stringify(data)).jsessionid)});
  }
}

Angular 用户界面图片:

在每次调用时,'jsessionid' 都会发生变化,如 '' 所示

【问题讨论】:

  • 您是否在连续调用时将旧的jsessionid 值发回?
  • 我们从 Shiro 获得了 'jsessionid',所以如果我们从同一个用户会话中调用登录 API,那么我们将得到相同的 'jsessionid'。在这里,当我从角度调用我的登录 API 时,每次调用都会创建新会话。所以每次'jsessionid'都在变化。
  • jsessionid 值用于标识服务器端的会话。客户端必须在每次调用时将其发回,否则将创建一个新会话。
  • 是的。但我不知道如何在客户端每次调用时发送 jsessionid(来自 angular 5 )。
  • 我不认识 Shiro,但通常这是作为 cookie 完成的。

标签: angular


【解决方案1】:

您需要在发送授权请求之前检查会话存储中的“jsessionid”。

login(){
 const data = {userName:"root", password:"root"};
 if(this.isLoggedIn()){
  return Observable.of(JSON.parse(sessionStorage.getItem('jsessionid')))
 }

 return this.http.post(this._url,{headers: this.headers},{params : data});
}

private isLoggedIn(): boolean {
 const result = !!(sessionStorage.getItem('jsessionid'));
 return result;
}

您还需要创建身份验证拦截器https://medium.com/@ryanchenkie_40935/angular-authentication-using-the-http-client-and-http-interceptors-2f9d1540eb8

【讨论】:

    【解决方案2】:

    会话管理将自动进行。

    如果我们当时在一台服务器上有客户端,而在另一台服务器上有后端,我们只需要添加“proxy.conf.json”文件。 并且需要在“package.json”文件中添加该文件条目。

    重要:- 将服务器 url 添加到“proxy.conf.json”中的端口号。 (服务器网址 输入到端口号)

    {
        "/": {
          "target": "https://localhost:30443",
          "secure": false
        }
     }
    

    在我的例子中,我在服务器 URL 中使用了一个额外的参数 /mainlayer。 (这是错误的。)

    {
       "/": {
         "target": "https://localhost:30443/mainlayer",
         "secure": false
       }
    }
    

    LoginService 类中添加额外的参数。

    private _url:string = "mainlayer/v1/login";
    

    【讨论】:

      【解决方案3】:

      拥有代理与您的问题无关......至少不是您所描述的

      只需添加

      this.http.{{requestverb}}({{endpoint}}, {withCredentials: true})
      

      例如

      this.http.get("/posts",{withCredentials:true});
      

      【讨论】:

        猜你喜欢
        • 2018-10-19
        • 1970-01-01
        • 2015-11-10
        • 2014-02-02
        • 2011-06-19
        • 1970-01-01
        • 2014-03-16
        • 2020-05-07
        • 2018-10-26
        相关资源
        最近更新 更多