AntDesign Pro + .NET Core 实现基于JWT的登录认证功能

2025-05-29 0 73

很多同学说AgileConfig的UI实在是太丑了。我想想也是的,本来这个项目是我自己使用的,一开始甚至连UI都没有,全靠手动在数据库里修改数据。后来加上了UI也是使用了老掉牙的bootstrap3做为基础样式。前台框架也是使用了angularjs,同样是老掉牙的东西。过年期间终于下决心翻新AgileConfig的前端UI。最后选择的前端UI框架为AntDesign Pro + React。至于为啥选Ant-Design Pro是因为他好看,而且流行,选择React是因为VUE跟Angular我都略知一二,干脆趁此机会学一学React为何物,为何这么流行。
登录的认证方案为JWT,其实本人对JWT不太感冒(请看这里《我们真的需要jwt吗?》),无奈大家都喜欢,那我也只能随大流。
其实基于ant-design pro的界面我已经翻的差不多了,因为它支持mock数据,所以我一行后台代码都没修改,已经把界面快写完了。从现在开始要真正的跟后端代码进行联调了。那么我们先从登录开始吧。先看看后端asp.net core方面会如何进行修改。

修改ASP.NET Core后端代码

?

1

2

3

4

5

6
"JwtSetting": {

"SecurityKey": "xxxxxxxxxxxx", // 密钥

"Issuer": "agileconfig.admin", // 颁发者

"Audience": "agileconfig.admin", // 接收者

"ExpireSeconds": 20 // 过期时间 s

}

在appsettings.json文件添加jwt相关配置。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24
public class JwtSetting

{

static JwtSetting()

{

Instance = new JwtSetting();

Instance.Audience = Global.Config["JwtSetting:Audience"];

Instance.SecurityKey = Global.Config["JwtSetting:SecurityKey"];

Instance.Issuer = Global.Config["JwtSetting:Issuer"];

Instance.ExpireSeconds = int.Parse(Global.Config["JwtSetting:ExpireSeconds"]);

}

public string SecurityKey { get; set; }

public string Issuer { get; set; }

public string Audience { get; set; }

public int ExpireSeconds { get; set; }

public static JwtSetting Instance

{

get;

}

}

定义一个JwtSetting类,用来读取配置。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19
public void ConfigureServices(IServiceCollection services)

{

services.AddMemoryCache();

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)

.AddJwtBearer(options =>

{

options.TokenValidationParameters = new TokenValidationParameters

{

ValidIssuer = JwtSetting.Instance.Issuer,

ValidAudience = JwtSetting.Instance.Audience,

IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtSetting.Instance.SecurityKey)),

};

});

services.AddCors();

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0).AddRazorRuntimeCompilation();

services.AddFreeSqlDbContext();

services.AddBusinessServices();

services.AddAntiforgery(o => o.SuppressXFrameOptionsHeader = true);

}

修改Startup文件的ConfigureServices方法,修改认证Scheme为JwtBearerDefaults.AuthenticationScheme,在AddJwtBearer方法内配置jwt相关配置信息。因为前后端分离项目所以有可能api跟ui部署在不同的域名下,所以开启Cors。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider)

{

if (env.IsDevelopment())

{

app.UseDeveloperExceptionPage();

}

else

{

app.UseMiddleware<ExceptionHandlerMiddleware>();

}

app.UseCors(op=> {

op.AllowAnyOrigin();

op.AllowAnyMethod();

op.AllowAnyHeader();

});

app.UseWebSockets(new WebSocketOptions()

{

KeepAliveInterval = TimeSpan.FromSeconds(60),

ReceiveBufferSize = 2 * 1024

});

app.UseMiddleware<WebsocketHandlerMiddleware>();

app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();

app.UseAuthorization();

app.UseEndpoints(endpoints =>

{

endpoints.MapDefaultControllerRoute();

});

}

修改Startup的Configure方法,配置Cors为Any。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28
public class JWT

{

public static string GetToken()

{

//创建用户身份标识,可按需要添加更多信息

var claims = new Claim[]

{

new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),

new Claim("id", "admin", ClaimValueTypes.String), // 用户id

new Claim("name", "admin"), // 用户名

new Claim("admin", true.ToString() ,ClaimValueTypes.Boolean) // 是否是管理员

};

var key = Encoding.UTF8.GetBytes(JwtSetting.Instance.SecurityKey);

//创建令牌

var token = new JwtSecurityToken(

issuer: JwtSetting.Instance.Issuer,

audience: JwtSetting.Instance.Audience,

signingCredentials: new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature),

claims: claims,

notBefore: DateTime.Now,

expires: DateTime.Now.AddSeconds(JwtSetting.Instance.ExpireSeconds)

);

string jwtToken = new JwtSecurityTokenHandler().WriteToken(token);

return jwtToken;

}

}

添加一个JWT静态类用来生成jwt的token。因为agileconfig的用户只有admin一个所以这里用户名,ID都直接写死。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33
[HttpPost("admin/jwt/login")]

public async Task<IActionResult> Login4AntdPro([FromBody] LoginVM model)

{

string password = model.password;

if (string.IsNullOrEmpty(password))

{

return Json(new

{

status = "error",

message = "密码不能为空"

});

}

var result = await _settingService.ValidateAdminPassword(password);

if (result)

{

var jwt = JWT.GetToken();

return Json(new {

status="ok",

token=jwt,

type= "Bearer",

currentAuthority = "admin"

});

}

return Json(new

{

status = "error",

message = "密码错误"

});

}

新增一个Action方法做为登录的入口。在这里验证完密码后生成token,并且返回到前端。
到这里.net core这边后端代码改动的差不多了。主要是添加jwt相关的东西,这些内容网上已经写了很多了,不在赘述。
下面开始修改前端代码。

修改AntDesign Pro的代码

AntDesign Pro已经为我们生成好了登录页面,登录的逻辑等,但是原来的登录是假的,也不支持jwt token做为登录凭证,下面我们要修改多个文件来完善这个登录。

?

1

2

3

4

5

6

7

8

9

10

11

12
export function setToken(token:string): void {

localStorage.setItem('token', token);

}

export function getToken(): string {

var tk = localStorage.getItem('token');

if (tk) {

return tk as string;

}

return '';

}

在utils/authority.ts文件内新增2个方法,用来存储跟获取token。我们的jwt token存储在localStorage里。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15
/** 配置request请求时的默认参数 */

const request = extend({

prefix: 'http://localhost:5000',

errorHandler, // 默认错误处理

credentials: 'same-origin', // 默认请求是否带上cookie,

});

const authHeaderInterceptor = (url: string, options: RequestOptionsInit) => {

const authHeader = { Authorization: 'Bearer ' + getToken() };

return {

url: `${url}`,

options: { ...options, interceptors: true, headers: authHeader },

};

};

request.interceptors.request.use(authHeaderInterceptor);

修改utils/request.ts文件,定义一个添加Authorization头部的拦截器,并且使用这个拦截器,这有每次请求的时候自动会带上这个头部,把jwt token传送到后台。
设置prefix为http://localhost:5000这是我们的后端api的服务地址,真正生产的时候会替换为正式地址。
设置credentials为same-origin。

?

1

2

3

4

5

6
export async function accountLogin(params: LoginParamsType) {

return request('/admin/jwt/login', {

method: 'POST',

data: params,

});

}

在services/login.ts文件内新增发起登录请求的方法。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42
effects: {

*login({ payload }, { call, put }) {

const response = yield call(accountLogin, payload);

yield put({

type: 'changeLoginStatus',

payload: response,

});

// Login successfully

if (response.status === 'ok') {

const urlParams = new URL(window.location.href);

const params = getPageQuery();

message.success('登录成功!');

let { redirect } = params as { redirect: string };

if (redirect) {

console.log('redirect url ' , redirect);

const redirectUrlParams = new URL(redirect);

if (redirectUrlParams.origin === urlParams.origin) {

redirect = redirect.substr(urlParams.origin.length);

if (redirect.match(/^\\/.*#/)) {

redirect = redirect.substr(redirect.indexOf('#') + 1);

}

} else {

window.location.href = '/';

return;

}

}

history.replace(redirect || '/');

}

},

reducers: {

changeLoginStatus(state, { payload }) {

setAuthority(payload.currentAuthority);

setToken(payload.token)

return {

...state,

status: payload.status,

type: payload.type,

};

},

},

修改models/login.ts文件,修改effects的login方法,在内部替换原来的fakeAccountLogin为accountLogin。同时修改reducers内部的changeLoginStatus方法,添加setToken的代码,这有修改后登录成功后token就会被存储起来。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19
effects: {

*fetch(_, { call, put }) {

const response = yield call(queryUsers);

yield put({

type: 'save',

payload: response,

});

},

*fetchCurrent(_, { call, put }) {

const response = {

name: '管理员',

userid: 'admin'

};

yield put({

type: 'saveCurrentUser',

payload: response,

});

},

},

修改models/user.ts文件,修改effects的fetchCurrent方法为直接返回response。本来fetchCurrent是会去后台拉当前用户信息的,因为agileconfig的用户就admin一个,所以我直接写死了。

AntDesign Pro + .NET Core 实现基于JWT的登录认证功能

让我们试一下登录吧:)
源码在这:https://github.com/kklldog/AgileConfig/tree/react_ui

到此这篇关于AntDesign Pro + .NET Core 实现基于JWT登录认证的文章就介绍到这了,更多相关.NET Core 登录认证内容请搜索快网idc以前的文章或继续浏览下面的相关文章希望大家以后多多支持快网idc!

原文链接:https://www.cnblogs.com/kklldog/archive/2021/03/04/ant-design-pro-with-netcore.html

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 AntDesign Pro + .NET Core 实现基于JWT的登录认证功能 https://www.kuaiidc.com/97580.html

相关文章

发表评论
暂无评论