drone源码-用户登录
drone并未使用普通的session管理机制,而是使用jwt机制,并使用cookie传输,如下
user_sess=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjEuNDg5MDUxNjc5ZSswOSwidGV4dCI6InFqdyIsInR5cGUiOiJzZXNzIn0.SD1uwHk_E7yT-74sVXHwrLPKmonbwRtQTzT8cNPrupg
_crsf=MTQ4NzkyMTYzOHxEdi1CQkFFQ180SUFBUkFCRUFBQU12LUNBQUVHYzNSeWFXNW5EQW9BQ0dOemNtWlRZV3gwQm5OMGNtbHVad3dTQUJCS2IzSk5lbVEwWlRaV05XdHdUalZrfHeLaVDFFSGOkLA19-4Y6G5gYkzJatkOn8oNnHj4eb6q;
cli运行依赖的参数包括
- DRONE_SERVER=http://${drone-server} ,server的地址,注意名称和agent的一样,但地址并不一致
- DRONE_TOKEN=fsajdflkas,token就是jwt的token,注意和DRONE_SECRET区别
我们可以直接将网站的jwt token直接拿来使用,但仅限于查询操作,其他操作会因为csrf限制无权限,参考【src/github.com/drone/drone/router/middleware/session/user.go】
// if this is a session token (ie not the API token)
// this means the user is accessing with a web browser,
// so we should implement CSRF protection measures.
if t.Kind == token.SessToken {
err = token.CheckCsrf(c.Request, func(t *token.Token) (string, error) {
return user.Hash, nil
})
// if csrf token validation fails, exit immediately
// with a not authorized error.
if err != nil {
c.AbortWithStatus(http.StatusUnauthorized)
return
}
}
这里实际上引申出一个session type的东西
const (
UserToken = "user"
SessToken = "sess"
HookToken = "hook"
CsrfToken = "csrf"
AgentToken = "agent"
)
网页授权使用的是SessionToken,而drone cli使用UserToken,具体通过drone网站右上角【ACCOUNT】,再回到左上角【SHOW TOKEN】,参考【src/github.com/drone/drone/router/router.go】
user := e.Group("/api/user")
{
user.POST("/token", server.PostToken)
user.DELETE("/token", server.DeleteToken)
}
cli是一堆的命令集合,具体参考官方文档,有些功能仅限cli使用
普通账户密码登录
drone代码中有一些相关的逻辑,但并不完整,所以不可用
// src/github.com/drone/drone/router/router.go
e.GET("/login", server.ShowLogin)
e.GET("/login/form", server.ShowLoginForm)
e.GET("/logout", server.GetLogout)
// src/github.com/drone/drone/server/pages.go
// ShowLoginForm displays a login form for systems like Gogs that do not
// yet support oauth workflows.
func ShowLoginForm(c *gin.Context) {
c.HTML(200, "login.html", gin.H{})
}
// src/github.com/drone/drone/server/template/files/login.html