package ControllerOauth2 import ( "dsSso/Const" "dsSso/Const/DefaultConst" "dsSso/Controller/ControllerRecaptcha" "dsSso/Dao/DaoBaseGlobal" "dsSso/Dao/DaoSysLoginPerson" "dsSso/Model" "dsSso/Service/ServiceJoinApp" "dsSso/Service/ServiceLoginPerson" "dsSso/Utils/AesUtil" "dsSso/Utils/CommonUtil" "dsSso/Utils/ConfigUtil" "dsSso/Utils/ConvertUtil" "dsSso/Utils/RedisStorage" "dsSso/Utils/RedisUtil" "dsSso/Utils/RsaUtil" "dsSso/Utils/SsoUtil" "encoding/base64" "encoding/json" "fmt" "github.com/RangelReale/osin" "github.com/dchest/captcha" "github.com/gin-gonic/gin" "github.com/tidwall/gjson" "io/ioutil" "net/http" "strconv" "strings" "time" ) //模块的路由配置 func Routers(r *gin.RouterGroup) { rr := r.Group("") //列表 rr.GET("/authorize", authorizeGet) //注册POST接口,用于验证 r.POST("/authorize", authorizePost) //用于授权码换取access_token r.POST("/access_token", accessToken) //获取验证码 r.GET("/getCaptcha", getCaptcha) //获取验证码图片 r.GET("/getCaptchaPng", getCaptchaPng) //退出接口 r.GET("/logout", logout) //清空登录限制 r.GET("/resetRemainCount", resetRemainCount) //微信登录 r.POST("/wxLogin", wxLogin) //检查OpenId r.GET("/checkOpenId", checkOpenId) //绑定用户 r.POST("/bindWxUser", bindWxUser) //解除绑定 r.POST("/unBindWxUser", unBindWxUser) //添加接入系统 r.POST("/AddClient", AddClient) //删除接入系统 r.POST("/DelClient", DelClient) return } // @Summary 获取验证码 // @Description 获取验证码(为了以后WEB服务器的集群扩展,将验证码保存到redis中,避免ip_hash) // @Tags 登录验证类 // @Accept application/x-www-form-urlencoded // @Produce json // @Success 200 {object} Model.Res // @Router /oauth2/getCaptcha [get] func getCaptcha(c *gin.Context) { //异常处理 defer func() { if err := recover(); err != nil { fmt.Printf("%s\n", err) } }() //自定义redis为存储器 captcha.SetCustomStore(&ControllerRecaptcha.RedisStoreBean) d := struct { CaptchaId string }{ captcha.NewLen(4), } if d.CaptchaId != "" { c.JSON(http.StatusOK, Model.Res{ Code: http.StatusOK, Msg: "获取成功", Data: d.CaptchaId, }) } else { c.JSON(http.StatusOK, Model.Res{ Code: http.StatusInternalServerError, Msg: "获取失败", Items: nil, }) } } // @Summary 获取验证码图片 // @Description 获取验证码图片 // @Tags 登录验证类 // @Accept application/x-www-form-urlencoded // @Produce json // @Param captchaId query string true "captchaId" // @Success 200 {string} string // @Router /oauth2/getCaptchaPng [get] // @X-LengthLimit [{"captchaId":"20,20"}] func getCaptchaPng(c *gin.Context) { //异常处理 defer func() { if err := recover(); err != nil { fmt.Printf("%s\n", err) } }() ControllerRecaptcha.ServeHTTP(c.Writer, c.Request) } //写Cookie func WriteCookie(context *gin.Context, identityId string, personId string, deviceId string) { //1、生成加密串 r, _ := AesUtil.Encrypt([]byte(identityId + "_" + personId + "_" + deviceId + "_" + ConvertUtil.Int64ToString(CommonUtil.GetCurrentTimestamp()))) //2、转base64 encodeString := base64.RawURLEncoding.EncodeToString([]byte(r)) //3、写cookie context.SetCookie(ConfigUtil.AccessToken, encodeString, 0, "/", "", false, true) } /** 功能:产生授权码 作者:黄海 时间:2020-03-13 */ func generateAuthCode(context *gin.Context, identityId string, personId string, deviceId string, typeId string) { //异常处理 defer func() { if err := recover(); err != nil { fmt.Printf("%s\n", err) } }() //写cookie WriteCookie(context, identityId, personId, deviceId) //如果是统一认证管理员登录 if identityId == "0" && personId == "0" { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusOK, Items: "/sso/static/ssoSystemList.html", }) return } else { //如果不是第三方系统跳转过来,而且还不是SSO管理员的情况下。 if context.PostForm("client_id") == "" && context.Query("client_id") == "" { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusOK, Msg: "不是第三方系统跳转过来,而且还不是SSO管理员", Items: "/sso/static/Error.html", }) return } //否则的话,返回授权码 req := context.Request resp := RedisStorage.OsinServer.NewResponse() defer resp.Close() if ar := RedisStorage.OsinServer.HandleAuthorizeRequest(resp, req); ar != nil { //标识验证通过 ar.Authorized = true ar.Expiration = 3600 * 2 //过期时间两小时 RedisStorage.OsinServer.FinishAuthorizeRequest(resp, req, ar) //用redis记录一下code--->personinfo的关系(黄海) personStr := "{\"identity_id\":\"" + identityId + "\",\"person_id\":\"" + personId + "\",\"device_id\":\"" + deviceId + "\"}" key := ConfigUtil.OAuth2RedisKeyPrefix + ":code_vs_person:" + resp.Output["code"].(string) RedisUtil.SET(key, personStr, 10*60*time.Second) } //返回数据 url := resp.URL code := resp.Output["code"].(string) state := resp.Output["state"].(string) //第三方的回调页面地址 oauthCallback := context.PostForm("oauth_callback") if oauthCallback == "" { oauthCallback = context.Query("oauth_callback") } //POST方式返回json数据 url = url + "?code=" + code + "&state=" + state + "&oauth_callback=" + oauthCallback if typeId == "POST" { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusOK, Items: url, }) return } else { //GET方式跳转回客户端的回调页 context.Redirect(302, url) return } } } // @Summary 获取access_token // @Description 获取access_token // @Tags 登录验证类 // @Accept application/x-www-form-urlencoded // @Produce json // @Param code query string false "code" // @Param refresh_token query string false "refresh_token" // @Success 200 {string} string // @Router /oauth2/access_token [post] func accessToken(context *gin.Context) { //异常处理 defer func() { if err := recover(); err != nil { fmt.Printf("%s\n", err) } }() req := context.Request resp := RedisStorage.OsinServer.NewResponse() defer resp.Close() var identityId string var personId string var deviceId string //授权码 code := context.PostForm("code") if code != "" { //从redis中获取回来 personInfo, err := RedisUtil.GET(ConfigUtil.OAuth2RedisKeyPrefix + ":code_vs_person:" + code) if err != nil { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusNotImplemented, Msg: "输入的授权码不正确或已过期!", }) return } //还原结构体 m := make(map[string]interface{}) json.Unmarshal([]byte(personInfo), &m) if err != nil { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusNotImplemented, Msg: "还原人员信息结构体失败!", }) return } identityId, _ = m["identity_id"].(string) personId, _ = m["person_id"].(string) deviceId, _ = m["device_id"].(string) if ar := RedisStorage.OsinServer.HandleAccessRequest(resp, req); ar != nil { ar.Authorized = true ar.Expiration = 3600 * 2 RedisStorage.OsinServer.FinishAccessRequest(resp, req, ar) } //2020-08-04 if resp.Output["access_token"] == nil { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusNotImplemented, Msg: "输入的授权码与其它相应的信息不匹配!", }) return } //自己动手,丰衣足食 accessToken := resp.Output["access_token"].(string) expiresIn := resp.Output["expires_in"].(int32) refreshToken := resp.Output["refresh_token"].(string) tokenType := resp.Output["token_type"].(string) identityIdInt, _ := strconv.Atoi(identityId) //记录refresh_token与identity_id,person_id关系 personStr := "{\"identity_id\":\"" + identityId + "\",\"person_id\":\"" + personId + "\",\"device_id\":\"" + deviceId + "\"}" k := ConfigUtil.OAuth2RedisKeyPrefix + ":refresh_token_vs_person:" + refreshToken RedisUtil.SET(k, personStr, time.Hour*24*30) //30天的有效期 personName, err := DaoSysLoginPerson.GetPersonName(identityId, personId) if err != nil { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusNotImplemented, Msg: "获取人员姓名信息失败!" + err.Error(), }) return } //返回json数据 context.JSON(http.StatusOK, gin.H{ "access_token": accessToken, "expires_in": expiresIn, "refresh_token": refreshToken, "token_type": tokenType, "identity_id": identityIdInt, "person_id": personId, "person_name": personName, "code": 200}) return } else { //刷新token clientRefreshToken := context.PostForm("refresh_token") if clientRefreshToken != "" { key := ConfigUtil.OAuth2RedisKeyPrefix + ":refresh_token_vs_person:" + clientRefreshToken personInfo, err := RedisUtil.GET(key) if err != nil { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusNotImplemented, Msg: "输入的刷新token不正确!", }) return } //还原结构体 m := make(map[string]interface{}) json.Unmarshal([]byte(personInfo), &m) if err != nil { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusNotImplemented, Msg: "还原人员信息结构体失败!", }) return } identityId, _ = m["identity_id"].(string) personId, _ = m["person_id"].(string) if ar := RedisStorage.OsinServer.HandleAccessRequest(resp, req); ar != nil { ar.Authorized = true RedisStorage.OsinServer.FinishAccessRequest(resp, req, ar) } accessToken := resp.Output["access_token"].(string) expiresIn := resp.Output["expires_in"].(int32) refreshToken := resp.Output["refresh_token"].(string) tokenType := resp.Output["token_type"].(string) identityIdInt, _ := strconv.Atoi(identityId) personIdInt, _ := strconv.Atoi(personId) //删除旧的refresh_token RedisUtil.DEL(key) //返回json数据 context.JSON(http.StatusOK, gin.H{ "access_token": accessToken, "expires_in": expiresIn, "refresh_token": refreshToken, "token_type": tokenType, "identity_id": identityIdInt, "person_id": personIdInt, "code": 200}) return } } } // @Summary 验证post // @Description 验证post // @Tags 登录验证类 // @Accept application/x-www-form-urlencoded // @Produce json // @Param captchaId formData string true "验证码id" // @Param value formData string true "验证码值" // @Param username formData string true "用户名" // @Param password formData string true "密码" // @Param device_id formData string true "设备ID" // @Param redirect_uri formData string false "第三方系统的接口回调地址" // @Param client_id formData string false "第三方系统的ID" // #Param oauth_callback formData string false "第三方系统的回调页面地址" // @Success 200 {object} Model.Res // @Router /oauth2/authorize [post] // @X-IntLimit ["device_id"] // @X-EmptyLimit ["username","password","captchaId","value"] func authorizePost(context *gin.Context) { //异常处理 defer func() { if err := recover(); err != nil { fmt.Printf("%s\n", err) } }() var identityId string var personId string var success bool var remainCount int //1、验证码 captchaId := context.PostForm("captchaId") value := context.PostForm("value") //2、用户名和密码 username := context.PostForm("username") encryptPwd := context.PostForm("password") //3、设备号 deviceId := context.PostForm("device_id") //4、校验函数根据redis的读取结果进行检查 var redisStore ControllerRecaptcha.RedisStore if redisStore.VerifyString(captchaId, value) { //对前端AES加密过的密码进行解密 b, err := base64.StdEncoding.DecodeString(encryptPwd) if err != nil { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusNotImplemented, Msg: "密码不是系统允许的base64方式!", }) return } decryptPwd, err := RsaUtil.RsaDecrypt(b) if err != nil { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusNotImplemented, Msg: "密码不是系统允许的加密方式!", }) return } //调用service层的用户名和密码校验办法判断是不是允许登录 ip := context.ClientIP() success, identityId, personId, _, remainCount, _ = ServiceLoginPerson.Login(username, string(decryptPwd), ip) if !success { //两次输入错误,不提醒 if remainCount >= 4 { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusNotImplemented, Msg: "用户名密码不正确或已禁用!", }) } else if remainCount > 0 { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusNotImplemented, Msg: "用户名密码不正确或已禁用!您还可以尝试" + CommonUtil.ConvertIntToString(remainCount-1) + "次,超出次数限制后,账号将被禁用2小时!", }) } else { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusNotImplemented, Msg: "账号已处于禁用状态,请稍后再试!", }) } return } } else { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusNotImplemented, Msg: "验证码不正确!", }) return } //验证通过的话,返回授权码 generateAuthCode(context, identityId, personId, deviceId, "POST") } // @Summary 登录验证跳转路由 // @Description 登录验证跳转路由 // @Tags 登录验证类 // @Accept application/x-www-form-urlencoded // @Produce json // @Param client_id query string true "client_id" // @Param redirect_uri query string true "redirect_uri" // @Param device_id query string true "device_id" // @Param oauth_callback query string true "第三方系统回跳的页面地址" // @Success 200 {string} string // @Router /oauth2/authorize [get] // @X-EmptyLimit ["client_id","redirect_uri","device_id","oauth_callback"] func authorizeGet(context *gin.Context) { //异常处理 defer func() { if err := recover(); err != nil { fmt.Printf("%s\n", err) } }() //客户端的client_id var paraClientId = context.Query("client_id") //回调接口地址 var redirectUri = context.Query("redirect_uri") //回调的页面地址 var oauthCallback = context.Query("oauth_callback") //oauth_callback的base64检查 _, err := base64.StdEncoding.DecodeString(oauthCallback) if err != nil { msg := "传入的oauth_callback不不是经过标准码的base64字符串!" context.JSON(http.StatusOK, map[string]interface{}{"success": false, "msg": msg}) return } //检查这个client_id是不是经过授权? client, err := RedisStorage.OAuth2RedisStorage.GetClient(paraClientId) if err != nil || client == nil { msg := "传入的client_id不在系统的允许范围内!" context.JSON(http.StatusOK, map[string]interface{}{"success": false, "msg": msg + err.Error()}) return } var sysUrl = client.GetRedirectUri() if sysUrl != redirectUri { msg := "回调地址与系统中保存的不一致!" context.JSON(http.StatusOK, map[string]interface{}{"success": false, "msg": msg}) return } var deviceId = context.Query("device_id") //注册验证是否登录的接口,这个GET接口是直接跳转走的 //此处判断人员是否存在本站下的session,如果有的话 var identityId = DefaultConst.IdentityId var personId = DefaultConst.PersonId SsoSessionId := SsoUtil.ReadSsoCookie(context) if SsoSessionId != "" { //取出UserData identityId, personId, _ = SsoUtil.AnalyzeSessionId(SsoSessionId) if identityId != "" && personId != "" { //为其生成授权码,并返回给客户端系统 generateAuthCode(context, identityId, personId, deviceId, "GET") return } } //如果没有本domain下的cookie,那么跳转到登录页 url := "/sso/static/index.html?redirect_uri=" + redirectUri + "&response_type=code&client_id=" + paraClientId + "&oauth_callback=" + oauthCallback context.Redirect(302, url) } // @Summary 退出统一认证 // @Description 退出统一认证 // @Tags 登录验证类 // @Accept application/x-www-form-urlencoded // @Param redirect_uri query string true "redirect_uri" // @Produce json // @Success 200 {string} string // @Router /oauth2/logout [get] func logout(context *gin.Context) { //异常处理 defer func() { if err := recover(); err != nil { fmt.Printf("%s\n", err) } }() //取出现在的cookie中的accessToken accessToken := SsoUtil.ReadSsoCookie(context) //获取所有接入系统的 list, _ := ServiceJoinApp.GetAppBaseList(1, Const.Int32Max, "") for i := range list { if list[i]["logout_uri"] != nil { //每个系统的退出地址 logoutUri := list[i]["logout_uri"].(string) //如果注册了退出地址的话 if len(logoutUri) > 0 { //开启协程进行调用 go func() { resp, err := http.Get(logoutUri + "?access_token=" + accessToken) if err != nil { fmt.Println(err) return } defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) fmt.Println(string(body)) }() } } } //清除cookie SsoUtil.DeleteSsoCookie(context) //判断来源是内网还是外网,是指客户端的IP地址,即浏览器的IP ipStart := strings.Split(context.Request.Host, ".")[0] isIntranetIP := strings.Index("10,192,172", ipStart) //外网 var s string if isIntranetIP < 0 { s = "defaultIndexWwUrl" } else { //内网 s = "defaultIndexNwUrl" } //跳转回去,系统默认统一的回调首页 list, err := DaoBaseGlobal.GetGlobalInfoByValue(s) if err != nil || len(list) == 0 { msg := "获取全局变量defaultIndexUrl失败!" context.JSON(http.StatusOK, map[string]interface{}{"success": false, "msg": msg}) return } globalValue := list[0]["global_value"].(string) context.Redirect(302, globalValue) return } // @Summary 重置错误重试次数限制 // @Description 重置错误重试次数限制 // @Tags 登录验证类 // @Accept application/x-www-form-urlencoded // @Produce json // @Param userName query string true "登录用的用户名" // @Success 200 {string} string // @Router /oauth2/resetRemainCount [get] // @X-EmptyLimit ["userName"] func resetRemainCount(context *gin.Context) { //异常处理 defer func() { if err := recover(); err != nil { fmt.Printf("%s\n", err) } }() userName := context.Query("userName") RedisUtil.DEL(Const.RemainCountRedisPrefix + userName) msg := "成功清除禁用标识!" context.JSON(http.StatusOK, map[string]interface{}{"success": true, "msg": msg}) return } // @Summary 微信登录 // @Description 微信登录 // @Tags 登录验证类 // @Accept application/x-www-form-urlencoded // @Produce json // @Param code formData string true "腾讯返回的code码" // @Success 200 {string} string // @Router /oauth2/wxLogin [post] // @X-EmptyLimit ["code"] func wxLogin(context *gin.Context) { //异常处理 defer func() { if err := recover(); err != nil { fmt.Printf("%s\n", err) } }() var code = context.PostForm("code") //对接微信,腾讯给的AK+SK appId := "wx3e0449144386938a" appSecret := "5175be38ddd689d1621df35cc22c192b" //验证的地址 var accessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" var accessTokenParams = fmt.Sprintf("appid=%s&secret=%s&code=%s&grant_type=authorization_code", appId, appSecret, code) //http调用 resp, err := http.Get(accessTokenUrl + "?" + accessTokenParams) if err != nil { fmt.Println(err) return } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if resp.StatusCode == 200 { //将返回结果转为json result := gjson.Get(string(body), "openid") if len(result.Str) == 0 { context.JSON(http.StatusOK, map[string]interface{}{"success": false, "openid": ""}) } else { context.JSON(http.StatusOK, map[string]interface{}{"success": true, "openid": result.Str}) } } else { context.JSON(http.StatusOK, map[string]interface{}{"success": false, "openid": ""}) } } // @Summary 检查OPENID的是否已经绑定 // @Description 检查OPENID的是否已经绑定 // @Tags 登录验证类 // @Accept application/x-www-form-urlencoded // @Produce json // @Param openid query string true "OpenId" // @Success 200 {string} string // @Router /oauth2/checkOpenId [get] func checkOpenId(context *gin.Context) { //异常处理 defer func() { if err := recover(); err != nil { fmt.Printf("%s\n", err) } }() openId := context.Query("openid") found, err, identityId, personId := ServiceLoginPerson.CheckOpenId(openId) if err != nil { context.JSON(http.StatusOK, map[string]interface{}{"success": false, "message": "检查OpenId失败!"}) return } //1、此OpenId已经存在挂接关系,那么写入相应的登录标识,并跳转到指定的页面 if found { //写cookie WriteCookie(context, CommonUtil.ConvertInt64ToString(identityId), personId, "1") //4、跳转到XXX页面,比如集成页,或者管理员的首页 context.JSON(http.StatusOK, map[string]interface{}{"success": true, "openId": openId}) } else { //2、如果此OpenId没有实现过挂接,应该跳转到绑定用户页面 context.JSON(http.StatusOK, map[string]interface{}{"success": false, "openId": openId}) } } // @Summary 绑定微信用户 // @Description 绑定微信用户 // @Tags 登录验证类 // @Accept application/x-www-form-urlencoded // @Produce json // @Param username query string true "username" // @Param password query string true "password" // @Param openId query string true "openId" // @Success 200 {string} string // @Router /oauth2/bindWxUser [get] func bindWxUser(context *gin.Context) { username := context.PostForm("username") encryptPwd := context.PostForm("password") openId := context.PostForm("openId") //1、检查用户名与密码是不是匹配 ip := context.ClientIP() b, err := base64.StdEncoding.DecodeString(encryptPwd) if err != nil { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusNotImplemented, Msg: "密码不是系统允许的base64方式!", }) return } decryptPwd, err := RsaUtil.RsaDecrypt(b) if err != nil { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusNotImplemented, Msg: "密码不是系统允许的加密方式!", }) return } //是否能登录 success, identityId, personId, _, remainCount, wxOpenId := ServiceLoginPerson.Login(username, string(decryptPwd), ip) if remainCount == 0 { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusNotImplemented, Msg: "密码输入错误次数过多,请两个小时后继续登录!", }) } //2、如果匹配了,那么这个登录名是不是已经绑定过openId了 if success { if len(wxOpenId) > 0 { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusNotImplemented, Msg: "此帐号已经绑定过微信号,无法再次绑定!如想修改微信号,请在个人中心通过修改!", }) return } else { //3、进行两者之间的绑定 _, err := ServiceLoginPerson.BindWxUser(identityId, personId, openId) if err != nil { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusNotImplemented, Msg: "在执行BindWxUser函数时出错!", }) return } //输出正确了~ //写cookie WriteCookie(context, identityId, personId, "1") context.JSON(http.StatusOK, Model.Res{ Code: http.StatusOK, Msg: "绑定成功!", }) } } else { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusNotImplemented, Msg: "用户名密码错误,无法绑定!", }) return } } // @Summary 解除绑定微信用户 // @Description 绑定微信用户 // @Tags 解除登录验证类 // @Accept application/x-www-form-urlencoded // @Produce json // @Success 200 {string} string // @Router /oauth2/unBindWxUser [get] func unBindWxUser(context *gin.Context) { identityId, _ := context.Cookie("identity_id") personId, _ := context.Cookie("person_id") //进行两者之间的解除绑定 _, err := ServiceLoginPerson.UnBindWxUser(identityId, personId) if err != nil { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusNotImplemented, Msg: "在执行unBindWxUser函数时出错!", }) return } context.JSON(http.StatusOK, Model.Res{ Code: http.StatusOK, Msg: "解除绑定成功!", }) } // @Summary 增加一个接入系统 // @Description 增加一个接入系统 // @Tags 统一认证管理 // @Accept application/x-www-form-urlencoded // @Produce json // @Param access_key formData string true "access_key" // @Param secret_key formData string true "secret_key" // @Param redirect_uri formData string true "redirect_uri" // @Success 200 {string} string // @Router /oauth2/AddClient [post] func AddClient(context *gin.Context) { ip := context.ClientIP() if ip != "127.0.0.1" { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusNotImplemented, Msg: "内部接口,只限本机进行调用!", }) return } accessKey := context.PostForm("access_key") secretKey := context.PostForm("secret_key") redirectUri := context.PostForm("redirect_uri") RedisStorage.OAuth2RedisStorage.CreateClient( &osin.DefaultClient{ Id: accessKey, Secret: secretKey, RedirectUri: redirectUri, }, ) context.JSON(http.StatusOK, Model.Res{ Code: http.StatusOK, Msg: "增加成功!", }) } // @Summary 删除一个接入系统 // @Description 删除一个接入系统 // @Tags 统一认证管理 // @Accept application/x-www-form-urlencoded // @Produce json // @Param access_key formData string true "access_key" // @Success 200 {string} string // @Router /oauth2/DelClient [post] func DelClient(context *gin.Context) { ip := context.ClientIP() if ip != "127.0.0.1" { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusNotImplemented, Msg: "内部接口,只限本机进行调用!", }) return } accessKey := context.PostForm("access_key") err := RedisStorage.OAuth2RedisStorage.DeleteClient( &osin.DefaultClient{ Id: accessKey, }, ) if err != nil { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusOK, Msg: "删除失败!" + err.Error(), }) } else { context.JSON(http.StatusOK, Model.Res{ Code: http.StatusOK, Msg: "删除成功!", }) } }