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.
复制代码

 

posted @   delphi中间件  阅读(142)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 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序列化对象
点击右上角即可分享
微信分享提示