[Optimization] 将微信扫码登录方式剥离,并设置为默认登录页,若无法使用微信扫码登录,则回退到密码登录页

This commit is contained in:
DAI Mingchen
2024-08-23 17:23:23 +08:00
repo.diff.parent 62705595a0
repo.diff.commit 2530394a2d
repo.diff.stats_desc%!(EXTRA int=13, int=60, int=51)

repo.diff.view_file

@@ -37,7 +37,7 @@ const (
LandingPageHome LandingPage = "/"
LandingPageExplore LandingPage = "/explore"
LandingPageOrganizations LandingPage = "/explore/organizations"
LandingPageLogin LandingPage = "/user/login"
LandingPageLogin LandingPage = "/user/login/wechat/official-account"
)
// Server settings

repo.diff.view_file

@@ -26,6 +26,7 @@ type PowerWechatOfficialAccountUserConfigType struct {
}
type OfficialAccountType struct {
Enabled bool
UserConfig PowerWechatOfficialAccountUserConfigType
TempQrExpireSeconds int
PowerWechat *PowerWechatOfficialAccountType.OfficialAccount
@@ -84,6 +85,8 @@ func createPowerWechatApp(userConfig PowerWechatOfficialAccountUserConfigType) {
})
if err != nil {
log.Warn("创建微信工具类 PowerWechat 失败,请检查 modules/setting/wechat.go ")
} else {
Wechat.OfficialAccount.Enabled = true
}
// TODO: remove init on fake redis

repo.diff.view_file

@@ -770,6 +770,7 @@ phone_sms_sent_success= SMS code sent, please check you phone message.
phone_sms_code_incorrect= The SMS code you input is incorrect.
change_phone_success= Phone updated successfully.
wechat_qr_login = WeChat QR
change_wechat= Update WeChat Account
wechat_official_account_qr_prompt=Scan QR with WeChat, and follow the Official Account.
wechat_official_account_qr_expired=WeChat QR expired.

repo.diff.view_file

@@ -769,6 +769,7 @@ phone_sms_sent_success=短信已发送,请查收
phone_sms_code_incorrect=短信验证码不正确
change_phone_success=手机号成功更新
wechat_qr_login = 微信二维码
change_wechat=更新微信
wechat_official_account_qr_prompt=使用微信扫描二维码,关注公众号
wechat_official_account_qr_expired=微信二维码已过期

repo.diff.view_file

@@ -38,9 +38,9 @@ import (
)
const (
tplSignIn base.TplName = "user/auth/signin" // for sign in page
tplSignInSms base.TplName = "user/auth/signin_sms" // 短信登录
tplSignInWexinQr base.TplName = "user/auth/signin_wechat_qr" // 微信公众号二维码登录
tplSignIn base.TplName = "user/auth/signin" // for sign in page
tplSignInSms base.TplName = "user/auth/signin_sms" // 短信登录
tplSignInWechatQr base.TplName = "user/auth/signin_wechat_qr" // 微信公众号二维码登录
tplSignUp base.TplName = "user/auth/signup" // for sign up page
TplActivate base.TplName = "user/auth/activate" // for activate user
@@ -163,8 +163,27 @@ func CheckAutoLogin(ctx *context.Context) bool {
return false
}
// 码登录页面渲染
// SignIn render sign in page
// SignInWechatQr 渲染微信扫码登录页面
func SignInWechatQr(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("sign_in")
ctx.Data["SignInWechatQrLink"] = setting.AppSubURL + "/user/login/wechat/official-account"
ctx.Data["PageIsSignIn"] = true
ctx.Data["PageIsLogin"] = true
ctx.Data["PageIsWechatQrLogin"] = true
ctx.Data["EnableSSPI"] = auth.IsSSPIEnabled(ctx)
_, err := GenerateWechatQr(ctx)
if err != nil {
wechatQrFallbackLoginURL := "/user/login"
log.Warn("微信创建二维码失败,回退到默认密码登录页面")
ctx.Redirect(setting.AppURL + wechatQrFallbackLoginURL)
return
}
ctx.HTML(http.StatusOK, tplSignInWechatQr)
}
// SignIn 渲染 密码登录页面
func SignIn(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("sign_in")
@@ -187,13 +206,9 @@ func SignIn(ctx *context.Context) {
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login"
ctx.Data["PageIsSignIn"] = true
ctx.Data["PageIsLogin"] = true
ctx.Data["PageIsPasswordLogin"] = true
ctx.Data["EnableSSPI"] = auth.IsSSPIEnabled(ctx)
_, err = GenerateWechatQr(ctx)
if err != nil {
log.Warn("微信创建二维码失败,跳过")
}
if setting.Service.EnableCaptcha && setting.Service.RequireCaptchaForLogin {
context.SetCaptchaData(ctx)
}
@@ -313,7 +328,7 @@ func SignInPost(ctx *context.Context) {
ctx.Redirect(setting.AppSubURL + "/user/two_factor")
}
// 短信登录页面渲染
// SignInSms 短信登录页面渲染
func SignInSms(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("sign_in")
ctx.Data["SignInSmsLink"] = setting.AppSubURL + "/user/login/sms"
@@ -321,11 +336,6 @@ func SignInSms(ctx *context.Context) {
ctx.Data["PageIsSmsLogin"] = true
ctx.Data["EnableSSPI"] = auth.IsSSPIEnabled(ctx)
_, err := GenerateWechatQr(ctx)
if err != nil {
log.Warn("微信创建二维码失败,跳过")
}
if setting.Service.EnableCaptcha && setting.Service.RequireCaptchaForLogin {
context.SetCaptchaData(ctx)
}
@@ -337,10 +347,6 @@ func SignInSms(ctx *context.Context) {
func SignInSmsPost(ctx *context.Context) {
}
// TODO: 扫描微信公众号二维码登录 POST
func SignInWechatQrPost(ctx *context.Context) {
}
// This handles the final part of the sign-in process of the user.
func handleSignIn(ctx *context.Context, u *user_model.User, remember bool) {
redirect := handleSignInFull(ctx, u, remember, true)

repo.diff.view_file

@@ -6,10 +6,10 @@ import (
gitea_web_context "code.gitea.io/gitea/services/context"
)
// WechatOfficialAccountQrSignIn 处理扫码登录用户Cookie保存等
// WechatOfficialAccountQrSignInSuccess 处理扫码登录用户Cookie保存等
//
// 由前端页面 window.location.href 跳转到 /user/login/wechat/official-account/success?ticket=${ticket}
func WechatOfficialAccountQrSignIn(ctx *gitea_web_context.Context) {
func WechatOfficialAccountQrSignInSuccess(ctx *gitea_web_context.Context) {
// 1. 取出 微信公众号二维码 ticket
wechatQrTicket := ctx.Base.Req.URL.Query().Get("ticket")

repo.diff.view_file

@@ -44,7 +44,7 @@ func Home(ctx *context.Context) {
}
// 未登录用户,重定向到登陆页面
ctx.Redirect(setting.AppSubURL + "/user/login")
ctx.Redirect(setting.AppSubURL + string(setting.LandingPageLogin))
}
// HomeSitemap renders the main sitemap

repo.diff.view_file

@@ -188,7 +188,7 @@ func verifyAuthWithOptions(options *common.VerifyOptions) func(ctx *context.Cont
if ctx.Req.URL.Path != "/user/events" {
middleware.SetRedirectToCookie(ctx.Resp, setting.AppSubURL+ctx.Req.URL.RequestURI())
}
ctx.Redirect(setting.AppSubURL + "/user/login")
ctx.Redirect(setting.AppSubURL + string(setting.LandingPageLogin))
return
} else if !ctx.Doer.IsActive && setting.Service.RegisterEmailConfirm {
ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
@@ -203,7 +203,7 @@ func verifyAuthWithOptions(options *common.VerifyOptions) func(ctx *context.Cont
if ctx.Req.URL.Path != "/user/events" {
middleware.SetRedirectToCookie(ctx.Resp, setting.AppSubURL+ctx.Req.URL.RequestURI())
}
ctx.Redirect(setting.AppSubURL + "/user/login")
ctx.Redirect(setting.AppSubURL + string(setting.LandingPageLogin))
return
}
@@ -506,7 +506,8 @@ func registerRoutes(m *web.Router) {
// "user/login" doesn't need signOut, then logged-in users can still access this route for redirection purposes by "/user/login?redirec_to=..."
m.Get("/user/login", auth.SignIn)
m.Get("/user/login/sms", auth.SignInSms)
m.Get("/user/login/wechat/official-account/success", auth.WechatOfficialAccountQrSignIn)
m.Get("/user/login/wechat/official-account", auth.SignInWechatQr)
m.Get("/user/login/wechat/official-account/success", auth.WechatOfficialAccountQrSignInSuccess)
m.Group("/user", func() {
m.Post("/login", web.Bind(forms.SignInForm{}), auth.SignInPost)

repo.diff.view_file

@@ -6,12 +6,5 @@
{{template "user/auth/signin_inner" .}}
</div>
</div>
{{if .wechatQrTicket}}
<div class="ui middle very relaxed page grid">
<div class="ui container column fluid">
{{template "user/auth/signin_wechat_qr_inner" .}}
</div>
</div>
{{end}}
</div>
{{template "base/footer" .}}

repo.diff.view_file

@@ -1,13 +1,24 @@
<overflow-menu class="ui secondary pointing tabular top attached borderless menu navbar secondary-nav">
<div class="overflow-menu-items tw-justify-center">
{{/* 1. + */}}
<a class="{{if .PageIsLogin}} active {{end}} item" rel="nofollow" href="{{AppSubUrl}}/user/login">
{{/* */}}
{{if .PageIsLogin}}
<a class="{{if .PageIsWechatQrLogin}} active {{end}} item" rel="nofollow" href="{{AppSubUrl}}/user/login/wechat/official-account">
{{ctx.Locale.Tr "settings.wechat_qr_login"}}
</a>
{{end}}
{{/* 2. */}}
{{if .PageIsLogin}}
<a class="{{if .PageIsPasswordLogin}} active {{end}} item" rel="nofollow" href="{{AppSubUrl}}/user/login">
{{ctx.Locale.Tr "password"}}
</a>
{{/* 2. */}}
<a class="{{if .PageIsSmsLogin}} active {{end}} item" rel="nofollow" href="{{AppSubUrl}}/user/login/sms">
{{ctx.Locale.Tr "settings.phone_sms_code"}}
</a>
{{end}}
{{/* 3. */}}
{{/* <a class="{{if .PageIsSmsLogin}} active {{end}} item" rel="nofollow" href="{{AppSubUrl}}/user/login/sms"> */}}
{{/* {{ctx.Locale.Tr "settings.phone_sms_code"}} */}}
{{/* </a> */}}
{{if or .EnableOpenIDSignIn .EnableSSPI}}
<a class="{{if .PageIsLogin}}active {{end}}item" rel="nofollow" href="{{AppSubUrl}}/user/login">

repo.diff.view_file

@@ -8,12 +8,5 @@
{{template "user/auth/signin_sms_inner" .}}
</div>
</div>
{{if .wechatQrTicket}}
<div class="ui middle very relaxed page grid">
<div class="ui container column fluid">
{{template "user/auth/signin_wechat_qr_inner" .}}
</div>
</div>
{{end}}
</div>
{{template "base/footer" .}}

repo.diff.view_file

@@ -31,8 +31,8 @@
.wechat-qr-container img {
display: inline-block; /* 设置为行内块级元素 */
vertical-align: middle; /* 垂直居中对齐 */
width: 132px;
height: 132px;
width: 50%;
height: 50%;
}
img.expire-mask {
@@ -140,7 +140,7 @@ function onLoginSuccess(qrTicket, openid) {
// 3. 处理用户登录凭证 跳转到后端
switch (window.location.pathname) {
case '/user/login':
case '/user/login/wechat/official-account':
// 登录页面扫码成功:跳转登录成功页面 /user/login/wechat/official-account/success?ticket=${qrTicket}
window.location.href = `${window.location.origin}/user/login/wechat/official-account/success?ticket=${qrTicket}&_=${Date.now()}`;
break;

repo.diff.view_file

@@ -112,7 +112,7 @@ func TestSettingLandingPage(t *testing.T) {
setting.LandingPageURL = setting.LandingPageLogin
req = NewRequest(t, "GET", "/")
resp = MakeRequest(t, req, http.StatusSeeOther)
assert.Equal(t, "/user/login", resp.Header().Get("Location"))
assert.Equal(t, setting.LandingPageLogin, resp.Header().Get("Location"))
setting.LandingPageURL = landingPage
}