使用带有grant_type authorization_code的Angular和Laravel passport对用户进行身份验证

4bbkushb  于 2023-02-05  发布在  Angular
关注(0)|答案(1)|浏览(139)

我想做的是为我的网站建立一个身份验证系统,使用Laravel passport作为后端,Angular作为前端
从官方文档中,我了解到我首先需要使用以下数据向/oauth/authorize route发出GET请求:

'client_id' : 1,
      'redirect_uri' : `${this.baseURL}`,
      'response_type' : 'code',
      'scope' : '',
      'state' : random_string(40)

然后使用上一个响应生成的代码向/oauth/token端点发出POST请求,以请求access_token
在当前状态下,当我使用postman发出第一个请求(/oauth/authorize)时,Laravel响应此错误:
Route [login] not defined.
据我所知,在请求端点授权之前,我首先需要以某种方式对用户进行身份验证,但我不知道如何做到这一点。
我是否需要定义一些登录逻辑?比如我的控制器中的一个登录函数,它应该对我的用户数据做些什么?
其他信息:

  • 我正在尝试对来自我的前端的用户进行身份验证,以使他们成为第一方用户
  • 我不想使用“密码授予令牌”,因为文档不推荐使用它
t9aqgxwy

t9aqgxwy1#

您不必每次都发送GET请求来接收身份验证系统的令牌,因为它们是静态的,并且是在执行命令时生成的:php工匠护照:安装.
此数据存储在数据库oauth_clients的表(模式)中。
例如,您可以在Angular应用程序的环境中编写和使用它们,而不必每次都向服务器和数据库发出不必要的请求。当然,如果个人访问客户端和密码授予客户端令牌不断更新,例如由CRON更新,那么当然,在这种情况下,向服务器发送一个初步的GET请求是必要的,也是有意义的。

身份验证系统客户端部分的代码如下所示:

  • 服务/授权/授权服务 *
import { Injectable } from '@angular/core'
import { HttpClient } from '@angular/common/http'
import { catchError, tap } from 'rxjs/operators'

interface IResponseHTTPLogin { // can be placed in a separate module or model at the discretion
  token_type: string
  expires_in: number
  access_token: string
  refresh_token: string
}

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

  /**
   * Auth Laravel Passport: Password Grant Client
   *
   * @private
   */
  private clientSecret: string = 'YOUR client secret token from oauth_clients table()' // <-- add enviroments
  private clientId: number = 2 // <-- id client from oauth_clients table() | add enviroments

  constructor (private http: HttpClient) {}

  /**
   * Login in cabinet.
   *
   * @param email
   * @param password
   */
  login (email: string, password: string) {
    return this.http.post<IResponseHTTPLogin>('/oauth/token', {
      grant_type: 'password',
      client_id: this.clientId,
      client_secret: this.clientSecret,
      username: email,
      password
    })
      .pipe(
        tap(({ access_token, refresh_token }) => {
          if (access_token) {
            this.setToken(access_token)
            this.setRefreshToken(refresh_token)
          }
        }),
        catchError((err) => {
          throw new Error(err)
        })
      )
  }

  getToken (): string {
    return sessionStorage.getItem('token') ?? ''
  }

  getRefreshToken (): string {
    return sessionStorage.getItem('token_refresh') ?? ''
  }

  protected setToken (token: string): void {
    sessionStorage.setItem('token', token) // OR use localStorage
  }

  protected setRefreshToken (refresh_token: string): void {
    sessionStorage.setItem('token_refresh', refresh_token)
  }

  isAuthenticate (): boolean {
    return !!sessionStorage.getItem('token')
  }

  logout (): void {
    sessionStorage.removeItem('token')
    sessionStorage.removeItem('token_refresh')
  }
}
  • 拦截器/令牌.拦截器 *
import { Injectable } from '@angular/core'
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor
} from '@angular/common/http'
import { Observable } from 'rxjs'
import { AuthService } from '../../services/auth/auth.service'

@Injectable()
export class TokenInterceptor implements HttpInterceptor {

  constructor (private authService: AuthService) {}

  intercept (request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    if (this.authService.isAuthenticate()) {
      request = request.clone({ setHeaders: { Authorization: `Bearer ${this.authService.getToken()}` } })
    }
    return next.handle(request)
  }
}

非常重要!为了满足您的授权请求并且不出现CORS错误,必须将其重定向到后端,例如使用以下方法使用代理。

  • 在项目的根目录下,创建一个proxy.conf.json文件。在其中添加以下代码:*
{
  "/oauth/token": {
    "target": "ADRESS YOR DOMAIN",
    "secure": false,
    "logLevel": "debug",
    "changeOrigin": true
  },
  "/api/*": {
    "target": "ADRESS YOR DOMAIN",
    "secure": false,
    "logLevel": "debug",
    "changeOrigin": true
  },
}
  • 接下来,告诉Angular所有请求都需要代理,为此,在package.json的scripts部分中指定:*
...
    "start": "ng serve --proxy-config proxy.conf.json", <------
 ...
  • 在AuthServiceProvider后端,您可以在 Boot ()方法中自定义令牌:*
...
Passport::tokensExpireIn(now()->addHours(24));
Passport::refreshTokensExpireIn(now()->addDays(30));
Passport::personalAccessTokensExpireIn(now()->addDays(30));
...

开发环境中的功能测试:

  • 拉腊维尔9.48
  • 拉腊维尔护照^11.5.1
  • Angular ^15

我想你会发现我的回答很有帮助。如果有什么不清楚的地方,问吧!

相关问题