gpt4 book ai didi

Angular 6 我是否必须在客户端生成 jwt 以匹配服务器或仅匹配服务器

转载 作者:行者123 更新时间:2023-12-04 15:50:26 24 4
gpt4 key购买 nike

我是 jwt 的新手,感谢您的耐心等待。

我在 PHP 中使用以下代码生成 jwt:

// Create token header as a JSON string
$header = json_encode(['typ' => 'JWT', 'alg' => 'HS256']);

// Create token payload as a JSON string
$payload = json_encode(['username' => $this->username, 'password' => $this->password]);

// Encode Header to Base64Url String
$base64UrlHeader = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($header));

// Encode Payload to Base64Url String
$base64UrlPayload = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($payload));

// Create Signature Hash
$signature = hash_hmac('sha256', $base64UrlHeader . "." . $base64UrlPayload, '<big secret>', true);

// Encode Signature to Base64Url String
$base64UrlSignature = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($signature));

所有这些只是为了生成签名 - $base64UrlSignature - 然后将其设置为 key :

$this->key = $base64UrlSignature;

        $token = array(
"iss" => $this->iss,
"aud" => $this->aud,
"iat" => $this->iat,
"nbf" => $this->nbf,
"data" => array(
"username" => $this->username,
"password" => $this->password
)
);

// generate jwt
$this->jwt = JWT::encode($token, $this->key);
echo json_encode(
array(
"status" => 401,
"id" => 0,
"uName" => "Guest",
"isAdmin" => "0",
"ts" => "2018-12-28 00:00:00",
"loggedIn" => false,
"msg" => "Combination of username and password not found",
"jwt" => $this->jwt
)
);

我的问题是,我是否必须在 Angular 的客户端执行相同的操作,以查看它是否与服务器生成的匹配?

到目前为止,我所阅读的所有内容都与生成 jwt 的服务器有关,然后在 Angular 中执行以下操作:

localStorage.setItem("jwt", res.jwt);

只需放在本地存储中。仅此而已吗?

难道不应该将服务器生成的 token 与客户端生成的 token 进行比较吗?

如果是这样,那么我该如何翻译上面的代码呢?例如,Angular 中与 Google 的 jwt PHP 类等价的是什么:

$this->jwt = JWT::encode($token, $this->key);

我正在向原始帖子添加代码。以下是我制作的拦截器:

import { ShoppingCartValuesService } from "./shopping-cart-values.service";
import { Injectable, Injector } from "@angular/core";
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest
} from "@angular/common/http";
import { Observable } from "rxjs/";
import * as jwt_decode from "jwt-decode";

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(public srvc: ShoppingCartValuesService) {}
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
const idToken = localStorage.getItem("jwt");

if (idToken) {
const cloned = req.clone({
headers: req.headers.set("Authorization", "Bearer " + idToken)
});
console.log("Decoded jwt token: ", this.getDecodedAccessToken(idToken));
return next.handle(cloned);
} else {
return next.handle(req);
}
}

getDecodedAccessToken(token: string): any {
try {
return jwt_decode(token);
} catch (error) {
console.log("error: ", error);
return false;
}
}
}

只要通过传递路由的点击处理程序 checkRequest() 在导航栏的链接中进行点击,它就会被调用,稍后会在整个 URL 之前添加:

  <li class="nav-item">
<a
class="nav-link"
data-toggle="tooltip"
title="Products"
routerLink="/products"
id="products"
(click)="checkRequest('/products')"
><span>Products</span></a
>
</li>

再次修改帖子以显示 (click)="checkRequest('/products'); 的 console.log 结果

检查请求方法:

checkRequest(url) {
const newUrl = this.srvc.serverBase + url;
this.clickResponse = this.http.get(newUrl, { observe: "body" });
console.log(
"newUrl: " +
newUrl +
" this.clickResponse: " +
JSON.stringify(this.clickResponse)
);

单击“/products”链接时来自 console.log:

newUrl: http://local.kronus:8001/products this.clickResponse: {"_isScalar":false,"source":{"_isScalar":false,"source":{"_isScalar":false,"source":{"_isScalar":true,"value":{"url":"http://local.kronus:8001/products","body":null,"reportProgress":false,"withCredentials":false,"responseType":"json","method":"GET","headers":{"normalizedNames":{},"lazyUpdate":null,"headers":{}},"params":{"updates":null,"cloneFrom":null,"encoder":{},"map":null},"urlWithParams":"http://local.kronus:8001/products"}},"operator":{"concurrent":1}},"operator":{}},"operator":{}}

拦截器似乎没有产生任何东西。有什么我想以某种方式包含拦截器的东西吗?

另一个更新:经过更多阅读,我意识到我需要将拦截器注入(inject)我的登录服务:

private authInt: AuthInterceptor

此外,我在登录服务中添加了:

clickResponse: Observable<any>;

我将 checkRequest 方法移动到登录服务:

checkRequest(url) {
const newUrl = this.appBase + url;
return (this.clickResponse = this.http.get(newUrl, { observe: "body" }));
}

在导航栏组件中,我将方法更改为以下调用服务的 checkRequest:

checkRequest(url) {
this.srvc.checkRequest(url).subscribe(data => {
console.log("after clicking login: ", data);
});
}

这是控制台中的 404 错误:

    HttpErrorResponse {headers: HttpHeaders, status: 404, statusText: "Not Found", url: "http://localhost:4200/login", ok: false, …}
error: "<!DOCTYPE html>↵<html lang="en">↵<head>↵<meta charset="utf-8">↵<title>Error</title>↵</head>↵<body>↵<pre>Cannot GET /login</pre>↵</body>↵</html>↵"
headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
message: "Http failure response for http://localhost:4200/login: 404 Not Found"
name: "HttpErrorResponse"
ok: false
status: 404
statusText: "Not Found"
url: "http://localhost:4200/login"

怎么可能找不到/login?我真的在登录页面上。是不是因为这个是在app做登录页面之前检查的?

这是当我意识到我不需要发送 '/login' 而是将 uri 发送到 api 时,这没有产生任何错误,但 header 中也没有 jwt。我试图在管理/产品页面上做同样的事情,下面一行似乎只是返回来自 api 的有效负载:

return (this.clickResponse = this.http.get(newUrl, { observe: "body" }));

然而,我在 header 部分没有看到任何 jwt 授权承载已通过。我错过了什么?

提前致谢

最佳答案

我缺少对 app.module.ts 的以下导入:

import { HTTP_INTERCEPTORS } from "@angular/common/http";
import { AuthInterceptor } from "./auth-interceptor";

{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true
}

在 providers 数组中使用 HTTP_INTERCEPTORS 并使用我制作的 auth 拦截器,自动附加到每个 http 请求 - 每个 http 请求。

此外,有时我试图将 auth 拦截器注入(inject)登录服务,当我最终意识到我需要将服务注入(inject)我的拦截器时,调用 this.srvc.getToken() 如下:

if (idToken) {
const cloned = req.clone({
headers: req.headers.set(
"Authorization",
"Bearer " + this.srvc.getToken()
)
});
// console.log("Decoded jwt token: ", this.getDecodedAccessToken(idToken));
return next.handle(cloned);
} else {
return next.handle(req);
}

从服务获取 token :

public getToken(): string {
return localStorage.getItem("jwt");
}

现在我的请求 header 如下所示:

Provisional headers are shown
Accept: application/json, text/plain, */*
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3Q6NDIwMCIsImF1ZCI6Imh0dHA6XC9cL2xvY2FsaG9zdDo0MjAwIiwiaWF0IjoxNTQ2OTU5NzUzLCJuYmYiOjE1NDY5NTg3NTMsImRhdGEiOnsibmFtZSI6InRhbUBrcm9udXNwcm9kdWN0aW9ucy5jb20iLCJwYXNzMSI6ImVhYmNkMTIzNDUifX0.GF1kFxdMe3Jd_paxu89Dve23ysguz4LGxXmGIDOz9Yc
Content-Type: application/json
Origin: http://localhost:4200
Referer: http://localhost:4200/login
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36

因为这些测试是在我的开发环境中进行的,所以我不会在 https 上运行,但是@paulsm4 是正确的,所有这些都需要通过 https 完成

顺便说一句,感谢您耐心等待我问了几个问题

关于Angular 6 我是否必须在客户端生成 jwt 以匹配服务器或仅匹配服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54058550/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com