【问题标题】:Angular 7 - Is there a way to store JSESSIONID and send it in every request?Angular 7 - 有没有办法存储 JSESSIONID 并在每个请求中发送它?
【发布时间】:2019-06-13 00:11:56
【问题描述】:

我正在开发一个带有 spring 后端的 angular 7 web 应用程序,我实现了安全性,所以当你使用正确的凭据登录时 spring 会给出一个 JSESSIONID cookie。如果我尝试使用邮递员登录,我会收到 cookie,一切正常,但从角度来看,即使服务器以 200 响应,它似乎也没有收到 cookie。

我的 login.service.ts:

import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';

@Injectable({
    providedIn: 'root'
})
export class LoginService {
    private apiURL = 'http://127.0.0.1:8080';

    constructor(
        private http: HttpClient
    ) { }

    login(credentials) {
        let params = new HttpParams()
            .set('username', credentials['username'])
            .set('password', credentials['password'])

        return this.http.post<any>(`${this.apiURL}/login`, credentials, {
            'headers': {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            'params': params
        })
    }
}

我在 login.component.ts 中的登录方法:

login(){
    this.loginService.login(this.credentials).subscribe((res) => {
      console.log(res)
    })
  }

我希望网络应用程序存储 cookie 并在每个请求中发送它,以便后端可以检查您是否实际登录

【问题讨论】:

    标签: angular spring


    【解决方案1】:

    您可以在路由器中发送数据,这正是我想要的。但在我的主项目中,JWT 信息存储在 localStorage 中:

    public saveToken(token: string): void {
        window.localStorage.setItem('jwtToken', token);
    }
    

    我很好奇是否有更好的“Angular”方式。

    我读完了这个:Netbasal's article 想到了你的问题,但我不确定这是一个解决方案还是很酷。

    【讨论】:

      【解决方案2】:

      在 Angular 中,您可以使用接口名称为 Storage 的打字稿。在登录服务中,您可以@Inject 存储并使用它,例如:

      const LOCAL_STORAGES = new InjectionToken<string>('user-session-local-storage');
      
      @Injectable()
      export class UserSessions {
      
          constructor(
              @Inject(LOCAL_STORAGES) private localStorage: Storage,
          ) {
      

      在保存会话的方法中可以调用:

      private setData(resource: string, value: string) {
              if (!value) {
                  return;
              }
      
              return this.localStorage.setItem(resource, value);
      }
      

      希望这会有所帮助!

      【讨论】:

        【解决方案3】:

        更适合您使用的方法是 angular interceptors。因此,您不必在任何地方都设置其他标题。在您的情况下设置 withCredentials: true 必须为您工作。

        import { Injectable } from "@angular/core";
        import {HttpInterceptor, HttpRequest,HttpHandler,HttpEvent,   
        HttpErrorResponse,HTTP_INTERCEPTORS} from "@angular/common/http";
        import { Observable, throwError } from "rxjs";
        import { catchError } from "rxjs/operators";
        
            @Injectable()
            export class CustomInterceptor implements HttpInterceptor {
        
              constructor() {}
        
              intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
               if (!request.headers.has("Content-Type"))
                 {
                      request = request.clone({
                      setHeaders: {ContentType: "application/x-www-form-urlencoded"},
                      withCredentials: true,
                      observe: 'response' as 'response'
                       });         
                }
        
                return next.handle(request );
              }
            }
        

        【讨论】:

        • 它似乎不起作用,我的观察选项出错:gyazo.com/c88cabb85596a7dc164ceb7df2fdcdc4
        • @AFlawlessGuy 你能试试我更新的答案吗?
        • 试过了,同样的错误,谢谢,这是我的代码:gyazo.com/657cf7d3ca888171c74a972de8241b2d
        • 您的后端 API 是公开的并且是实时的吗?这样我也可以测试。
        • 不,它是本地的。但是我的一位同事已经解决了这个问题,我知道怎么做。但似乎问题出在后端,至少我是这么认为的。
        猜你喜欢
        • 2022-11-23
        • 1970-01-01
        • 1970-01-01
        • 2017-01-03
        • 2013-01-16
        • 2019-02-20
        • 1970-01-01
        • 2013-01-06
        • 2016-07-12
        相关资源
        最近更新 更多