You need to enable JavaScript to run this app. Delphi:如何为基于DelphiMVCFramework的RESTful服务器创建有状态连接
优惠活动
大模型
产品
解决方案
定价
更多

Delphi:如何为基于DelphiMVCFramework的RESTful服务器创建有状态连接

DelphiMVCFramework 3.2.1 会话式登录认证实现方案

你当前每次请求携带Basic认证信息的方式存在重复传参、凭证多次传输的问题,DMVC 3.2.1版本本身就内置了完全匹配你诉求的整套认证机制,不需要从零开发。

核心机制匹配度

这套内置的Token会话认证流程完全覆盖你的需求:

  • 提供独立的登录入口,用户一次性提交用户名密码完成校验
  • 校验通过后服务端生成临时有效Token返回,后续业务请求仅需携带该Token,无需重复传递用户名密码
  • 支持主动调用登出接口立即作废Token
  • 内置超时机制,到设定无操作时长后Token自动失效,不需要客户端主动处理

服务端配置步骤

DMVC内置的TMVCClientTokenAuth中间件已经封装了Token生成、校验、失效全流程,只需要按以下步骤挂载即可:

  1. 在Web模块初始化阶段创建中间件实例,自定义用户名密码校验逻辑、设置超时时间
    uses
      MVCFramework.Auth, MVCFramework.TokenAuth;
    
    procedure TServerWebModule.WebModuleInit(Sender: TObject);
    begin
      // 初始化Token认证中间件
      FMVCClientTokenAuth := TMVCClientTokenAuth.Create(
        // 自定义凭证校验逻辑,可替换为数据库查询逻辑
        function(AContext: TWebContext; const AUsername, APassword: string; var AUser: TPeerUser): Boolean
        begin
          Result := (AUsername = '合法用户名') and (APassword = '合法密码');
          if Result then
            AUser.UserName := AUsername;
        end,
        // 设置会话超时时间:单位秒,30分钟无操作自动失效
        30 * 60
      );
    
      // 挂载路由白名单:登录接口允许匿名访问,其余业务接口必须携带合法Token
      Middleware.Add(
        procedure(AContext: TWebContext; const ANext: TProc)
        begin
          if AContext.Request.PathInfo = '/api/login' then
            ANext()
          else
            FMVCClientTokenAuth.ProcessRequest(AContext, ANext);
        end
      );
    end;
    
  2. 在控制器中实现对应的登录、登出接口,直接调用中间件内置方法即可,不需要手写Token生成逻辑
    [Path('/api')]
    TAuthController = class(TMVCController)
    public
      [HttpPost, Path('/login'), AllowAnonymous]
      procedure Login;
    
      [HttpGet, Path('/logout')]
      procedure Logout;
    end;
    
    procedure TAuthController.Login;
    var
      Username, Password, GeneratedToken: string;
    begin
      Username := Context.Request.Params['username'];
      Password := Context.Request.Params['password'];
      GeneratedToken := FMVCClientTokenAuth.GenerateToken(Username, Password);
      Render(
        TJSONObject.Create(
          'token', GeneratedToken,
          'expires_in', FMVCClientTokenAuth.DefaultSessionTimeout
        )
      );
    end;
    
    procedure TAuthController.Logout;
    var
      CurrentToken: string;
    begin
      CurrentToken := Context.Request.Headers['X-Auth-Token'];
      FMVCClientTokenAuth.InvalidateToken(CurrentToken);
      Render(TJSONObject.Create('message', '登出成功'));
    end;
    

客户端(TIdHTTP)改造

只需要对现有请求逻辑做最小修改,不需要改动原有业务代码结构:

  1. 应用启动后首次调用/api/login接口,将返回的Token存在本地模块(如你现有DM模块的私有变量中)
  2. 后续所有业务请求,删除原有的Basic认证、用户名密码设置代码,仅需在自定义请求头中携带存储的Token即可
    改造后的原getGroupsFromServer方法示例:
    procedure TDM.getGroupsFromServer;
    var
      Http: TIdHTTP;
      ReqStr: string;
    begin
      try
        Http := TIdHTTP.Create(nil);
        Http.ReadTimeout := 10000;
        Http.Request.ContentType := 'application/json';
        Http.Request.CharSet := 'utf-8';
        Http.Request.Accept := '*/*';
        // 替换原有的Basic认证配置,携带本地存储的Token
        Http.Request.CustomHeaders.AddValue('X-Auth-Token', Self.StoredLoginToken);
        ReqStr := Http.Get('http://' + SERVER_IP + ':8080/api/groups');
        groupsJSON := ReqStr;
        dsGroups.LoadFromJSONArrayString(ReqStr);
        dsGroups.First;
      finally
        Http.Free;
      end;
    end;
    
  3. 用户主动登出时,携带本地存储的Token调用/api/logout接口,服务端就会立即作废对应Token

注意事项

  • Token默认通过X-Auth-Token请求头传递,不需要再使用Basic认证头,避免凭证多次暴露
  • 超时时间可以根据业务场景调整,高安全场景可缩短到15分钟,普通场景30分钟即可
  • 服务端默认将会话Token存在内存中,重启服务端后所有已生成的Token都会自动失效,不会出现残留会话风险

内容的提问来源于stack exchange,提问作者user2005049

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.03 02:36:03