mirror of https://github.com/mindoc-org/mindoc.git
钉钉免登显示钉钉用户名和头像,配置XSRF,修复一些BUG
parent
350bdc4d02
commit
9141487aa3
|
@ -7,6 +7,7 @@ runmode = "${MINDOC_RUN_MODE||dev}"
|
||||||
sessionon = true
|
sessionon = true
|
||||||
sessionname = mindoc_id
|
sessionname = mindoc_id
|
||||||
copyrequestbody = true
|
copyrequestbody = true
|
||||||
|
enablexsrf = true
|
||||||
|
|
||||||
#系统完整URL(http://doc.iminho.me),如果该项不设置,会从请求头中获取地址。
|
#系统完整URL(http://doc.iminho.me),如果该项不设置,会从请求头中获取地址。
|
||||||
baseurl="${MINDOC_BASE_URL}"
|
baseurl="${MINDOC_BASE_URL}"
|
||||||
|
@ -209,6 +210,20 @@ log_level="${MINDOC_LOG_LEVEL||Alert}"
|
||||||
# 是否异步生成日志,默认是 true
|
# 是否异步生成日志,默认是 true
|
||||||
log_is_async="${MINDOC_LOG_IS_ASYNC||TRUE}"
|
log_is_async="${MINDOC_LOG_IS_ASYNC||TRUE}"
|
||||||
|
|
||||||
|
##########钉钉应用相关配置##############
|
||||||
|
|
||||||
|
# 企业钉钉ID
|
||||||
|
dingtalk_corpid="${MINDOC_DINGTALK_CORPID}"
|
||||||
|
|
||||||
|
# 钉钉AppKey
|
||||||
|
dingtalk_app_key="${MINDOC_DINGTALK_APPKEY}"
|
||||||
|
|
||||||
|
# 钉钉AppSecret
|
||||||
|
dingtalk_app_secret="${MINDOC_DINGTALK_APPSECRET}"
|
||||||
|
|
||||||
|
# 钉钉登录默认只读账号
|
||||||
|
dingtalk_tmp_reader="${MINDOC_DINGTALK_READER}"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,7 @@ const CaptchaSessionName = "__captcha__"
|
||||||
const RegexpEmail = "^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"
|
const RegexpEmail = "^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"
|
||||||
|
|
||||||
//允许用户名中出现点号
|
//允许用户名中出现点号
|
||||||
// const RegexpAccount = `^[a-zA-Z][a-zA-Z0-9\.-]{2,50}$`
|
const RegexpAccount = `^[a-zA-Z][a-zA-Z0-9\.-]{2,50}$`
|
||||||
const RegexpAccount = `[a-zA-Z0-9\.-]{2,50}$`
|
|
||||||
|
|
||||||
// PageSize 默认分页条数.
|
// PageSize 默认分页条数.
|
||||||
const PageSize = 10
|
const PageSize = 10
|
||||||
|
|
|
@ -32,9 +32,12 @@ func (c *AccountController) referer() string {
|
||||||
|
|
||||||
func (c *AccountController) Prepare() {
|
func (c *AccountController) Prepare() {
|
||||||
c.BaseController.Prepare()
|
c.BaseController.Prepare()
|
||||||
c.EnableXSRF = true
|
c.EnableXSRF = beego.AppConfig.DefaultBool("enablexsrf", true)
|
||||||
c.Data["xsrfdata"] = template.HTML(c.XSRFFormHTML())
|
c.Data["xsrfdata"] = template.HTML(c.XSRFFormHTML())
|
||||||
c.Data["corpID"] = beego.AppConfig.String("dingtalk_corpid")
|
c.Data["corpID"] = beego.AppConfig.String("dingtalk_corpid")
|
||||||
|
if !c.EnableXSRF {
|
||||||
|
return
|
||||||
|
}
|
||||||
if c.Ctx.Input.IsPost() {
|
if c.Ctx.Input.IsPost() {
|
||||||
token := c.Ctx.Input.Query("_xsrf")
|
token := c.Ctx.Input.Query("_xsrf")
|
||||||
if token == "" {
|
if token == "" {
|
||||||
|
@ -138,7 +141,7 @@ func (c *AccountController) Login() {
|
||||||
func (c *AccountController) DingTalkLogin() {
|
func (c *AccountController) DingTalkLogin() {
|
||||||
c.Prepare()
|
c.Prepare()
|
||||||
|
|
||||||
code := c.GetString("code")
|
code := c.GetString("dingtalk_code")
|
||||||
if code == "" {
|
if code == "" {
|
||||||
c.JsonResult(500, "获取身份信息失败", nil)
|
c.JsonResult(500, "获取身份信息失败", nil)
|
||||||
}
|
}
|
||||||
|
@ -160,7 +163,14 @@ func (c *AccountController) DingTalkLogin() {
|
||||||
c.StopRun()
|
c.StopRun()
|
||||||
}
|
}
|
||||||
|
|
||||||
username, err := dingtalkAgent.GetUserNameByCode(code)
|
userid, err := dingtalkAgent.GetUserIDByCode(code)
|
||||||
|
if err != nil {
|
||||||
|
beego.Warn("钉钉自动登录失败 ->", err)
|
||||||
|
c.JsonResult(500, "自动登录失败", nil)
|
||||||
|
c.StopRun()
|
||||||
|
}
|
||||||
|
|
||||||
|
username, avatar, err := dingtalkAgent.GetUserNameAndAvatarByUserID(userid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
beego.Warn("钉钉自动登录失败 ->", err)
|
beego.Warn("钉钉自动登录失败 ->", err)
|
||||||
c.JsonResult(500, "自动登录失败", nil)
|
c.JsonResult(500, "自动登录失败", nil)
|
||||||
|
@ -171,6 +181,10 @@ func (c *AccountController) DingTalkLogin() {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
member.LastLoginTime = time.Now()
|
member.LastLoginTime = time.Now()
|
||||||
_ = member.Update("last_login_time")
|
_ = member.Update("last_login_time")
|
||||||
|
member.Account = username
|
||||||
|
if avatar != "" {
|
||||||
|
member.Avatar = avatar
|
||||||
|
}
|
||||||
|
|
||||||
c.SetMember(*member)
|
c.SetMember(*member)
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,10 +179,6 @@ func (m *Member) httpLogin(account, password string) (*Member, error) {
|
||||||
return nil, ErrMemberAuthMethodInvalid
|
return nil, ErrMemberAuthMethodInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpH := md5.New()
|
|
||||||
tmpH.Write([]byte(password))
|
|
||||||
password = strings.ToUpper(hex.EncodeToString(tmpH.Sum(nil)))
|
|
||||||
|
|
||||||
val := url.Values{
|
val := url.Values{
|
||||||
"account": []string{account},
|
"account": []string{account},
|
||||||
"password": []string{password},
|
"password": []string{password},
|
||||||
|
|
|
@ -227,7 +227,7 @@ limit ?;`
|
||||||
for _, member := range members {
|
for _, member := range members {
|
||||||
item := KeyValueItem{}
|
item := KeyValueItem{}
|
||||||
item.Id = member.MemberId
|
item.Id = member.MemberId
|
||||||
item.Text = member.Account + "(" + member.RealName + ")"
|
item.Text = member.Account + "[" + member.RealName + "]"
|
||||||
items = append(items, item)
|
items = append(items, item)
|
||||||
}
|
}
|
||||||
result.Result = items
|
result.Result = items
|
||||||
|
|
|
@ -27,8 +27,8 @@ func NewDingTalkAgent(appSecret, appKey string) *DingTalkAgent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserNameByCode 通过临时code获取当前用户信息
|
// GetUserIDByCode 通过临时code获取当前用户ID
|
||||||
func (d *DingTalkAgent) GetUserNameByCode(code string) (string, error) {
|
func (d *DingTalkAgent) GetUserIDByCode(code string) (string, error) {
|
||||||
urlEndpoint, err := url.Parse("https://oapi.dingtalk.com/user/getuserinfo")
|
urlEndpoint, err := url.Parse("https://oapi.dingtalk.com/user/getuserinfo")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -62,8 +62,48 @@ func (d *DingTalkAgent) GetUserNameByCode(code string) (string, error) {
|
||||||
return "", errors.New(fmt.Sprintf("登录错误: %.0f, %s", errcode, rdata["errmsg"].(string)))
|
return "", errors.New(fmt.Sprintf("登录错误: %.0f, %s", errcode, rdata["errmsg"].(string)))
|
||||||
}
|
}
|
||||||
|
|
||||||
username := rdata["name"].(string)
|
userid := rdata["userid"].(string)
|
||||||
return username, nil
|
return userid, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUserNameAndAvatarByUserID 通过userid获取当前用户姓名和头像
|
||||||
|
func (d *DingTalkAgent) GetUserNameAndAvatarByUserID(userid string) (string, string, error) {
|
||||||
|
urlEndpoint, err := url.Parse("https://oapi.dingtalk.com/topapi/v2/user/get")
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
query := url.Values{}
|
||||||
|
query.Set("access_token", d.AccessToken)
|
||||||
|
|
||||||
|
urlEndpoint.RawQuery = query.Encode()
|
||||||
|
urlPath := urlEndpoint.String()
|
||||||
|
|
||||||
|
resp, err := http.PostForm(urlPath, url.Values{"userid": {userid}})
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析钉钉返回数据
|
||||||
|
var rdata map[string]interface{}
|
||||||
|
err = json.Unmarshal(body, &rdata)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
errcode := rdata["errcode"].(float64)
|
||||||
|
if errcode != 0 {
|
||||||
|
return "", "", errors.New(fmt.Sprintf("登录错误: %.0f, %s", errcode, rdata["errmsg"].(string)))
|
||||||
|
}
|
||||||
|
|
||||||
|
userinfo := rdata["result"].(map[string]interface{})
|
||||||
|
username := userinfo["name"].(string)
|
||||||
|
avatar := userinfo["avatar"].(string)
|
||||||
|
return username, avatar, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAccesstoken 获取钉钉请求Token
|
// GetAccesstoken 获取钉钉请求Token
|
||||||
|
|
|
@ -99,7 +99,7 @@
|
||||||
})
|
})
|
||||||
|
|
||||||
var formData = $("form").serializeArray()
|
var formData = $("form").serializeArray()
|
||||||
formData.push({"name": "code", "value": info.code})
|
formData.push({"name": "dingtalk_code", "value": info.code})
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: "{{urlfor "AccountController.DingTalkLogin"}} ",
|
url: "{{urlfor "AccountController.DingTalkLogin"}} ",
|
||||||
|
|
Loading…
Reference in New Issue