Demo背景
因想启动一个新项目,而用户中心是我并未涉及过的业务领域,且用户登录认证等逻辑实现即一劳永逸,在日后的项目中均可直接复制使用, 故使用spring boot+Spring Security实现JWT模式完成以下功能:
- form 或 Json登录
- 手机验证码登录
- oauth2登录(gitee、微信公众号)
- 微信小程序登录
项目地址:https://gitee.com/michea/gou-dan-fromwork/tree/2023-security/
注:为Demo启动更容易,用户信息和权限信息等用户数据均为假数据, 验证码等缓存使用本地内存。
相比先从理论了解原理,我更倾向于让项目跑起来,观察代码执行的整个流程,所以我会在代码执行的关键节点打上日志方便使用者了解整个链路的执行顺序。
即直接通过接口测试起来日志会给到惊喜。
测试
一.登录
1.form或Json登录(注:login_type为登陆类型:0-form,1-json,默认为form)
curl --request POST \ --url http://localhost:16607/login \ --header 'content-type: multipart/form-data' \ --form username=admin \ --form password=admin \ --form login_type=0
2.手机验证码登录
发送验证码
curl --request GET \ --url http://localhost:16607/captcha/15224016451
根据验证码登录
curl --request POST \ --url 'http://localhost:16607/clogin?phone=15224016451&captcha=684125'
3.OAuth2(gitee和微信公众号登录)
gitee登录:http://localhost:16607/oauth2/authorization/gitee
微信公众号登录:http://localhost:16607/oauth2/authorization/wechat
4.微信小程序登录(流程:前端获取wxCode,请求此接口)
curl "http://localhost:16607/wechatapp/refresh" ^
-H "Connection: keep-alive" ^
-H "X-Auth-Token: " ^
-H "User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1 wechatdevtools/1.05.2203070 MicroMessenger/8.0.5 Language/zh_CN webview/" ^
-H "content-type: application/json" ^
-H "Accept: */*" ^
-H "Sec-Fetch-Site: cross-site" ^
-H "Sec-Fetch-Mode: cors" ^
-H "Sec-Fetch-Dest: empty" ^
-H "Referer: https://servicewechat.com/wx26707ba013dadd47/devtools/page-frame.html" ^
--data-binary "^{^\^"wxCode^\^":^\^"0b1lA3ml2vsD2c4729nl2QfoNe0lA3mZ^\^",^\^"userPic^\^":^\^"https://thirdwx.qlogo.cn/mmopen/vi_32/POgEwh4mIHO4nibH0KlMECNjjGxQUq24ZEaGT4poC6icRiccVGKSyXwibcPq4BWmiaIGuG1icwxaQX6grC9VemZoJ8rg/132^\^",^\^"iv^\^":^\^"SCwXz44zYg1srjEPc585VQ==^\^",^\^"encryptedData^\^":^\^"zrJTCwrQH1x9xvdGFr7Tj4jQKP5Gu+mwgcqJx3XpIckEcIiPUQTxYtPm+mnsULU3LRgM8PD9EBe/Ny6mAy1kYKcLU/86N8qKwPxSM/aAEUMgPHNZbYoUjc2uupy6/k0G6QcEJyZNDv7ArRJYf4W8nopOqa4cq42UysqtNQOTDMCutjQaPA26aZqPyTGG5rMvrPPBLe0NZz1hcj6+JMVQjTzuWxFQjYjJtGyN99cNoR8fwVtdzgVzla7v+I7FHpEzfizm8S5UYsnNf5Z9eqTZa4gRt15fqgsHKXNtTvADi+DtQZvbcdULLaftoQd8EE8R7nei+Osn450d8DLcdg4q7Hoo25tS1hG4NGK1QGpDgxnuHsZoioPZkVKUb9qpnEMTImwMaCYPdD880/W1FI1Nw1uxbyenUGyHALXxd7OLyP/OTs15QpLl+OA1ZXCw0tvK^\^",^\^"tenantCompanyId^\^":22^}" ^
--compressed
二.验证客户登陆状态(注:每次登录需更换Authorization值)
curl --request POST \ --url http://localhost:16607/login/success \ --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhbGwiLCJhdWQiOiJhZG1pbiIsInJvbGVzIjoiW1wiUk9MRV9BUFBcIixcIlJPTEVfQURNSU5cIl0iLCJpc3MiOiJmZWxvcmQuY24iLCJleHAiOiIyMDIzLTEwLTE0IDE1OjMwOjE3IiwiaWF0IjoiMjAyMy0wOS0xNCAxNTozMDoxNyIsImp0aSI6ImExM2I3N2FjLTM0MDEtNGNjZS1iY2MyLTk0OGQ5MDg0MTZhNSJ9.EEuqyEy8ZyxHc-KGqeNDou6b_kMbCd6CrIDE_P9UYTo4ex20j2IIKylKPnM3TeqqsEfF1ZQjsNeMPl26okV9xvDwTZex4A43aChR4_h3mrl-ywXvcNc71PxQNyopeT-cTCVrW_hrLItjTvNPv-OT4RssEG5Z37lGhXDBpUHQg1Y'
三.退出登录
curl --request POST \ --url http://localhost:16607/logout \ --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhbGwiLCJhdWQiOiJhZG1pbiIsInJvbGVzIjoiW1wiUk9MRV9BUFBcIixcIlJPTEVfQURNSU5cIl0iLCJpc3MiOiJmZWxvcmQuY24iLCJleHAiOiIyMDIzLTEwLTE0IDE1OjMwOjE3IiwiaWF0IjoiMjAyMy0wOS0xNCAxNTozMDoxNyIsImp0aSI6ImExM2I3N2FjLTM0MDEtNGNjZS1iY2MyLTk0OGQ5MDg0MTZhNSJ9.EEuqyEy8ZyxHc-KGqeNDou6b_kMbCd6CrIDE_P9UYTo4ex20j2IIKylKPnM3TeqqsEfF1ZQjsNeMPl26okV9xvDwTZex4A43aChR4_h3mrl-ywXvcNc71PxQNyopeT-cTCVrW_hrLItjTvNPv-OT4RssEG5Z37lGhXDBpUHQg1Y'
配置介绍
为了更方便理解,项目中除了Oauth2登陆方式,我们均用了同一种配置模式
配置逻辑为:
- Filter 拦截登录请求
- 生成包含登录信息属性对象-XXXToken(如:有属性UserName和PassWord),
- Fiilter将对象XXXToken对象交给一个可以验证其属性是否正确的处理器-XXXProvider
所有的配置都放在了:SecurityConfiguration