mormot2.jwt.pas
unit mormot2.jwt; /// <author>cxg 2024-7-13</author> /// {iss (issuer):签发人 { exp (expiration time):过期时间 sub (subject):主题 aud (audience):受众 nbf (Not Before):生效时间 iat (Issued At):签发时间 jti (JWT ID):编号 } interface uses mormot.crypt.jwt, mormot.core.base, SysUtils; function sign(user: array of const; const iss: RawUtf8 = 'iss'; const sub: RawUtf8 = 'sub'; const aud: RawUtf8 = 'aud'; nbf: TDateTime = 0; exp: Integer = 0; signature: PRawUtf8 = nil): RawUtf8; function verifySign(const token: RawUtf8): TJwtContent; implementation { HS256 使用同一个「secret_key」进行签名与验证(对称加密)。一旦 secret_key 泄漏,就毫无安全性可言了。 因此 HS256 只适合集中式认证,签名和验证都必须由可信方进行。 传统的单体应用广泛使用这种算法,但是请不要在任何分布式的架构中使用它! RS256 是使用 RSA 私钥进行签名,使用 RSA 公钥进行验证。公钥即使泄漏也毫无影响,只要确保私钥安全就行。 RS256 可以将验证委托给其他应用,只要将公钥给他们就行。 ES256 和 RS256 一样,都使用私钥签名,公钥验证。算法速度上差距也不大,但是它的签名长度相对短很多(省流量),并且算法强度和 RS256 差不多。 } const secret_key = 'cxg'; //一旦 secret_key 泄漏,就毫无安全性可言了。 function sign(user: array of const; const iss, sub, aud: RawUtf8; nbf: TDateTime; exp: Integer; signature: PRawUtf8 = nil): RawUtf8; { procedure TForm1.Button1Click(Sender: TObject); var ltoken: string; sessionid: integer; begin ltoken := token(['username', 'user2', 'password', 'pwd']); memo1.Text:=ltoken; sessionid := ltoken.GetHashCode; memo2.Lines.Add('sessionid:' + sessionid.ToString); end; } var jwt: TJwtAbstract; begin jwt := TJwtHS256.Create(secret_key, 0, [jrcIssuer], []); Result := jwt.Compute(user, iss, sub, aud, nbf, exp, signature); jwt.Free; end; function verifySign(const token: RawUtf8): TJwtContent; { procedure TForm1.Button3Click(Sender: TObject); var r: TJwtContent; s: RawUtf8; begin r := verifyToken(Memo1.Text); if r.result = jwtValid then begin Memo2.Lines.Add('验证token成功'); Memo2.Lines.Add('Issue: ' + r.reg[jrcIssuer]); Memo2.Lines.Add('Subject: ' + r.reg[jrcSubject]); Memo2.Lines.Add('user: ' + r.data.S['username']); Memo2.Lines.Add('password: ' + r.data.S['password']); end; end; } var jwt: TJwtAbstract; begin jwt := TJwtHS256.Create(secret_key, 0, [jrcIssuer], []); jwt.Verify(token, Result); jwt.Free; end; end.
调用演示
unit Unit1; {$mode delphi}{$H+} interface uses mormot2.jwt, mormot.crypt.jwt, mormot.core.base, mormot.crypt.secure, mormot.crypt.core, Generics.Collections, Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls; type Tuserdata = record username: string; pwd: string; other: string; end; //var sessions: TDictionary<integer, Tuserdata>; //sessionid,userdata { TForm1 } TForm1 = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Memo1: TMemo; Memo2: TMemo; procedure Button1Click(Sender: TObject); procedure Button3Click(Sender: TObject); private public end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.Button1Click(Sender: TObject); //客户端签名和sessionid var ltoken: string; sessionid: integer; begin //根据用户名、密码。。等数据,生成签名 ltoken := sign(['username', 'user2', 'password', 'pwd', 'param1', 'value1']); memo1.Text:=ltoken; sessionid := ltoken.GetHashCode; //生成用户的唯一sessionid memo2.Lines.Add('sessionid:' + sessionid.ToString); end; procedure TForm1.Button3Click(Sender: TObject); //服务端验签和获取用户数据 var r: TJwtContent; s: RawUtf8; begin r := verifySign(Memo1.Text); //验签 if r.result = jwtValid then //验签通过 begin Memo2.Lines.Add('验证签名成功'); Memo2.Lines.Add('Issue: ' + r.reg[jrcIssuer]); //获取用户数据 Memo2.Lines.Add('Subject: ' + r.reg[jrcSubject]); Memo2.Lines.Add('user: ' + r.data.S['username']); Memo2.Lines.Add('password: ' + r.data.S['password']); memo2.Lines.Add('param1: ' + r.data.S['param1']); end; end; end.
本文来自博客园,作者:{咏南中间件},转载请注明原文链接:https://www.cnblogs.com/hnxxcxg/p/17157277.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2021-02-26 微服务配置中心
2021-02-26 微服务日志
2012-02-26 插件框架之BUILD WITH RUNTIME PACKAGE选项
2012-02-26 提交主从表的多个已经修改的数据
2012-02-26 压缩OLEVARIANT数据
2012-02-26 oleVariant序列化对象