Ant Design Pro V5 与 IdentityServer 实现 Password 模式的登录

最近处于休息状态,想趁着休息时间,为自己做一个后台。

后端框架选用了 Abp。之前公司使用了一些自研的框架,但由于人力资源有限,后期框架的升级及维护都是比较耗时,这次干脆直接使用Abp,即省心又能快速上手写逻辑。

前端框架选用了 Ant Design Pro V5,前端已经很多很多年没有写过了,边学习边实践吧。

Password 模式

建议采用 authorization_code 的方式。github 有一些开源的 oidc 库, 方便前端使用。Oidc 方式有时间会写一下。

 

 Abp

可以通过Cli 或者在线模板快速生成项目框架,创建为模块即可。

开始 | ABP.IO

 

Identity Server

 

添加客户端

可以使用 IdentityServer Admin UI 作为管理工具,本文采用代码配置方式。

DbMigrator 项目配置文件增加

"Tech_Admin": {
    "ClientId": "Tech_Admin",
    "ClientSecret": "1q2w3e*",
    "RootUrl": "http://localhost:8000"
},

 

Domain 项目,修改种子文件IdentityServerDataSeedContributor

     //Admin Web Client
        var adminWebClientId = configurationSection["Tech_Admin:ClientId"];
        if (!webClientId.IsNullOrWhiteSpace())
        {
            var webClientRootUrl = configurationSection["Tech_Admin:RootUrl"].EnsureEndsWith('/');

            await CreateClientAsync(
                name: adminWebClientId,
                scopes: commonScopes,
                grantTypes: new[] {GrantType.ResourceOwnerPassword},
                secret: (configurationSection["Tech_Admin:ClientSecret"] ?? "1q2w3e*").Sha256(),
                redirectUri: $"{webClientRootUrl}signin-oidc",
                postLogoutRedirectUri: $"{webClientRootUrl}signout-callback-oidc",
                frontChannelLogoutUri: $"{webClientRootUrl}Account/FrontChannelLogout",
                requirePkce: false,
                corsOrigins: new[]
                {
                    webClientRootUrl.RemovePostFix("/"),
                }
            );
        }    
View Code

 

Endpoint

可以参考官方文档

Token Endpoint — IdentityServer4 1.0.0 documentation 

 

执行Migration

运行DbMigrator,生成初始化数据;EF Migration 也可以通过此执行,比较方便。可以配合 jenkins 做成数据库脚本自动化发布。

 

Ant Design

 

修改 LoginParams 

type LoginParams = {
    username?: string;
    password?: string;
    autoLogin?: boolean;
    type?: string;
    client_id?: string;
    grant_type?: string;
    client_secret?: string;
  };
View Code

 

修改登录接口

记得对  client_id,grant_type,client_secret 赋值。

export async function login(body: API.LoginParams, options?: { [key: string]: any }) {
  return request<API.LoginResult>('/account/connect/token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded;',
    },
    data: new URLSearchParams(body),
    ...(options || {}),
  });
}
View Code

 

存储Token

const handleSubmit = async (values: API.LoginParams) => {
    try {
      // 登录
      const msg = await login({ ...values, type });
      if (msg.expires_in > 0) {
        const defaultLoginSuccessMessage = intl.formatMessage({
          id: 'pages.login.success',
          defaultMessage: '登录成功!',
        });
        setAccessToken(msg.access_token);
        message.success(defaultLoginSuccessMessage);
        await fetchUserInfo();
        /** 此方法会跳转到 redirect 参数所在的位置 */
        if (!history) return;
        const { query } = history.location;
        const { redirect } = query as { redirect: string };
        history.push(redirect || '/');
        return;
      }
      console.log(msg);
      // 如果失败去设置用户错误信息
      setUserLoginState(msg);
    } catch (error) {
      const defaultLoginFailureMessage = intl.formatMessage({
        id: 'pages.login.failure',
        defaultMessage: '登录失败,请重试!',
      });
      message.error(defaultLoginFailureMessage);
    }
  };
View Code

至此已经实现了Token的存储,登录成功后,会获取用户信息,此处也需要进行修改,修改方式与修改Token 类似。

 

携 Token 调用Api (拦截器)

可以参考:https://pro.ant.design/zh-CN/docs/request

修改app.tsx,主要引用  import request from 'umi-request';

request.interceptors.request.use((url, options) => {
  let token = localStorage.getItem('access_token');
  if (null === token) {
    token = '';
  }
  const authHeader = { Authorization: `Bearer ${token}` };
  return {
    url: url,
    options: { ...options, interceptors: true, headers: authHeader },
  };
});
View Code

 

 

结尾

至此,登录部分已经修改完毕,还是比较快速的。

 

 

posted @ 2022-04-01 00:30  高堂古秋  阅读(565)  评论(0)    收藏  举报