這是一個基於Go語言開發的單點登錄系統,實現手機號註冊、手機號+驗證碼登錄、手機號+密碼登錄、賬號登出等功能,用戶認證採用cookie和jwt兩種方式。收發短信相關方法已提供,僅需根據短信通道提供商提供的接口做相應的參數配置即可使用。
環境介紹
golang語言:go1.13.3+ 、
數據庫:mysql5.7
緩存:redis3.0
項目地址
https://github.com/guyan0319/go-sso
依賴包:
github.com/dgrijalva/jwt-go
github.com/gin-gonic/gin
github.com/go-xorm/xorm
github.com/go-sql-driver/mysql
注意:項目代碼依賴管理工具採用的go-modules,需要了解的移步https://github.com/guyan0319/golang_development_notes/blob/master/zh/1.10.md
數據請求類型
Content-Type: application/json
注:這個一定要注意,其他類型服務端不識別。
快速開始
1、數據庫
sql文件在data目錄下,新建數據庫名,通過mysql管理工具或登錄mysql數據庫直接創建數據庫名,並導入ssodb.sql文件到數據庫,完成數據庫結構創建。具體方法這裏不再贅述。
2、配置mysql、redis
配置文件在conf目錄下,修改 mysql.go、redis.go配置成你自己的實際環境。
3、啓動
go run main.go
4、測試
我們可以採用postman等工具,進行客戶端瀏覽器模擬操作,也可以通過curl實現。
這裏以curl工具爲例:
註冊手機號
$ curl -X POST "http://127.0.0.1:8282/signup/mobile" -i -d '{"mobile":"13522227564","passwd":"123456","code": "111111"}'
結果
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 86 100 28 100 58 1750 3625 --:--:-- --:--:-- --:--:-- 86000HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Tue, 09 Jun 2020 08:59:36 GMT
Content-Length: 28
{"code":200,"msg":"success"}
注:code參數值只要隨意6位數即可,示例中服務端並沒有配置短信通道,驗證code代碼已註釋。
手機號+密碼 登錄
$ curl -X POST "http://127.0.0.1:8282/login" -i -d '{"mobile":"13522227564","passwd":"123456"}'
結果
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 69 100 28 100 41 451 661 --:--:-- --:--:-- --:--:-- 1112HTTP/1.1 200 OK
Access_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjEsImV4cCI6MTU5MTg1ODIwMX0.OMpRhdX2wXm1BuRmeaZtSH7L3skXhNhYc0YYUTQf7WI
Content-Type: application/json; charset=utf-8
Refresh_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjEsImV4cCI6MTU5MTg2MDAwMX0.Hglo9i8pxFGcRcvMw8mUvXlT2JLrHSC6ocQqJseknq8
Set-Cookie: Access_Token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjEsImV4cCI6MTU5MTg1ODIwMX0.OMpRhdX2wXm1BuRmeaZtSH7L3skXhNhYc0YYUTQf7WI; Path=/; Max-Age=86400; HttpOnly
Set-Cookie: Refresh_Token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjEsImV4cCI6MTU5MTg2MDAwMX0.Hglo9i8pxFGcRcvMw8mUvXlT2JLrHSC6ocQqJseknq8; Path=/; Max-Age=86400; HttpOnly
Set-Cookie: UserId=1; Path=/; Max-Age=86400; HttpOnly
Date: Wed, 10 Jun 2020 06:50:01 GMT
Content-Length: 28
{"code":200,"msg":"success"}
手機號+驗證碼登錄
$ curl -X POST "http://127.0.0.1:8282/login/mobile" -i -d '{"mobile":"13522227564","code":"123456"}'
結果
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 68 100 28 100 40 163 233 --:--:-- --:--:-- --:--:-- 397HTTP/1.1 200 OK
Access_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjEsImV4cCI6MTU5MTk1NDIxOX0.FK-6ofW-ni8E7BcQ1tH9Z4vzQHDBbnyIcDZLEytRrfQ
Content-Type: application/json; charset=utf-8
Refresh_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjEsImV4cCI6MTU5MTk1NjAxOX0.gJzzho2gP1nNrkUKdtvMh0R3jGFZpA-ku0dWDvLftu0
Set-Cookie: Access_Token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjEsImV4cCI6MTU5MTk1NDIxOX0.FK-6ofW-ni8E7BcQ1tH9Z4vzQHDBbnyIcDZLEytRrfQ; Path=/; Max-Age=86400; HttpOnly
Set-Cookie: Refresh_Token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjEsImV4cCI6MTU5MTk1NjAxOX0.gJzzho2gP1nNrkUKdtvMh0R3jGFZpA-ku0dWDvLftu0; Path=/; Max-Age=86400; HttpOnly
Set-Cookie: UserId=1; Path=/; Max-Age=86400; HttpOnly
Date: Thu, 11 Jun 2020 09:30:19 GMT
Content-Length: 28
{"code":200,"msg":"success"}
獲取用戶信息
使用上面登錄獲取的Access_Token獲取用戶信息。
$ curl "http://127.0.0.1:8282/my/info" -b "Access_Token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjEsImV4cCI6MTU5MTk1NDIxOX0.FK-6ofW-ni8E7BcQ1tH9Z4vzQHDBbnyIcDZLEytRrfQ"
結果
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 73 100 73 0 0 73000 0 --:--:-- --:--:-- --:--:-- 73000{"code":200,"data":{"id":1,"name":"","email":"","mobile":"135****27564"}}
查看手機號是否存在
$ curl -X POST "http://127.0.0.1:8282/signup/mobile/exist" -i -d '{"mobile":"13522227564"}'
結果
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 61 100 37 100 24 37000 24000 --:--:-- --:--:-- --:--:-- 61000HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Wed, 10 Jun 2020 07:40:50 GMT
Content-Length: 37
{"code":200,"data":{"is_exist":true}}
access token 續期
$ curl -X POST "http://127.0.0.1:8282/renewal" -i -b "Access_Token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjEsImV4cCI6MTU5MTk1NDIxOX0.FK-6ofW-ni8E7BcQ1tH9Z4vzQHDBbnyIcDZLEytRrfQ;Rfresh_Token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjEsImV4cCI6MTU5MTk1NjAxOX0.gJzzho2gP1nNrkUKdtvMh0R3jGFZpA-ku0dWDvLftu0"
結果:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 28 100 28 0 0 595 0 --:--:-- --:--:-- --:--:-- 595HTTP/1.1 200 OK
Access_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjEsImV4cCI6MTU5MTk1NTEzMn0.KCNVQ39HoMZFG-Xl0xwDrVdhQO_w4-tDxWY0ebyhfyk
Content-Type: application/json; charset=utf-8
Refresh_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjEsImV4cCI6MTU5MTk1NjkzMn0.XijN8ZjPbZkhjJB33igti3dSm1tfd2kp_iNRtPqpwyM
Set-Cookie: Access_Token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjEsImV4cCI6MTU5MTk1NTEzMn0.KCNVQ39HoMZFG-Xl0xwDrVdhQO_w4-tDxWY0ebyhfyk; Path=/; Max-Age=86400; HttpOnly
Set-Cookie: Refresh_Token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjEsImV4cCI6MTU5MTk1NjkzMn0.XijN8ZjPbZkhjJB33igti3dSm1tfd2kp_iNRtPqpwyM; Path=/; Max-Age=86400; HttpOnly
Date: Thu, 11 Jun 2020 09:45:32 GMT
Content-Length: 28
{"code":400,"msg":"success"}
登出系統
$ curl -X POST "http://127.0.0.1:8282/logout" -b "Access_Token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjEsImV4cCI6MTU5MTk1NDIxOX0.FK-6ofW-ni8E7BcQ1tH9Z4vzQHDBbnyIcDZLEytRrfQ"
結果
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 28 100 28 0 0 28000 0 --:--:-- --:--:-- --:--:-- 28000{"code":200,"msg":"success"}
小結
僅使用jwt實現單點登錄會遇到兩個問題
- 用戶無法主動登出,即服務端發出token後,無法主動銷燬token,用戶還可以用通過token訪問系統,本項目增加了緩存登出用戶token到黑名單的方式,變相實現登出。
- token續期問題,access_token攜帶有效期,有效期過了無法自動續期。本項目提供了續期接口(renewal),服務端在生成access_token同時還會生成refresh_token(有效期比access_token長),用戶可以通過有效的refresh_token和access_token訪問renewal接口重新獲取新的refresh_token和access_token。
在使用過程如遇到任何問題,歡迎issues。