wip: 继续 oauth
This commit is contained in:
39
internal/serve/handler/authorize.go
Normal file
39
internal/serve/handler/authorize.go
Normal file
@ -0,0 +1,39 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"github.com/loveuer/nf"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func Authorize(c *nf.Ctx) error {
|
||||
|
||||
// 解析查询参数
|
||||
clientID := c.Query("client_id")
|
||||
responseType := c.Query("response_type")
|
||||
redirectURI := c.Query("redirect_uri")
|
||||
scope := c.Query("scope")
|
||||
|
||||
// 检查客户端 ID 和其他参数
|
||||
// 在实际应用中,你需要检查这些参数是否合法
|
||||
if clientID != "12345" || responseType != "code" || redirectURI != "http://localhost:8080/callback" {
|
||||
return c.Status(http.StatusBadRequest).SendString("Invalid request")
|
||||
}
|
||||
|
||||
// 显示授权页面给用户
|
||||
_, err := c.Write([]byte(`
|
||||
<html>
|
||||
<head><title>Authorization</title></head>
|
||||
<body>
|
||||
<h1>Do you want to authorize this application?</h1>
|
||||
<form action="/approve" method="post">
|
||||
<input type="hidden" name="client_id" value="` + clientID + `"/>
|
||||
<input type="hidden" name="redirect_uri" value="` + redirectURI + `"/>
|
||||
<input type="hidden" name="scope" value="` + scope + `"/>
|
||||
<button type="submit">Yes, I authorize</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
`))
|
||||
|
||||
return err
|
||||
}
|
77
internal/serve/handler/login.go
Normal file
77
internal/serve/handler/login.go
Normal file
@ -0,0 +1,77 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"github.com/loveuer/nf"
|
||||
"github.com/loveuer/nf/nft/resp"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
var (
|
||||
//go:embed serve_login.html
|
||||
page string
|
||||
)
|
||||
|
||||
func LoginPage(c *nf.Ctx) error {
|
||||
type Req struct {
|
||||
ClientID string `query:"client_id"`
|
||||
ClientSecret string `query:"client_secret"`
|
||||
Scope string `query:"scope"`
|
||||
RedirectURI string `query:"redirect_uri"`
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
req = new(Req)
|
||||
)
|
||||
|
||||
if err = c.QueryParser(req); err != nil {
|
||||
return resp.Resp400(c, err.Error())
|
||||
}
|
||||
|
||||
if req.ClientID == "" || req.ClientSecret == "" || req.RedirectURI == "" {
|
||||
return resp.Resp400(c, req)
|
||||
}
|
||||
|
||||
// todo: 验证 client id, client secret, scoop
|
||||
|
||||
// todo: 如果用户是已登录状态,则直接带上信息返回到 authorize 页面
|
||||
|
||||
return c.RenderHTML("login", page, map[string]interface{}{
|
||||
"client_id": req.ClientID,
|
||||
"client_secret": req.ClientSecret,
|
||||
"redirect_uri": req.RedirectURI,
|
||||
"scope": req.Scope,
|
||||
})
|
||||
}
|
||||
|
||||
func LoginAction(c *nf.Ctx) error {
|
||||
type Req struct {
|
||||
Username string `form:"username"`
|
||||
Password string `form:"password"`
|
||||
ClientId string `form:"client_id"`
|
||||
ClientSecret string `form:"client_secret"`
|
||||
RedirectURI string `form:"redirect_uri"`
|
||||
Scope string `form:"scope"`
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
req = new(Req)
|
||||
)
|
||||
|
||||
if err = c.BodyParser(req); err != nil {
|
||||
return resp.Resp400(c, err.Error())
|
||||
}
|
||||
|
||||
// todo: 验证用户登录是否成功,等等
|
||||
|
||||
queries := make(url.Values)
|
||||
queries.Add("client_id", req.ClientId)
|
||||
queries.Add("client_secret", req.ClientSecret)
|
||||
queries.Add("redirect_uri", req.RedirectURI)
|
||||
queries.Add("scope", req.Scope)
|
||||
|
||||
return c.Redirect("/api/oauth/v2/authorize?"+queries.Encode(), http.StatusFound)
|
||||
}
|
55
internal/serve/handler/serve_login.html
Normal file
55
internal/serve/handler/serve_login.html
Normal file
@ -0,0 +1,55 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.jade.min.css"
|
||||
>
|
||||
<title>Server Login</title>
|
||||
<style>
|
||||
body {
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<h3>欢迎来到 Pro</h3>
|
||||
<form action="/api/oauth/v2/login" method="POST">
|
||||
<fieldset>
|
||||
<label>
|
||||
Username
|
||||
<input
|
||||
name="username"
|
||||
placeholder="username"
|
||||
autocomplete="given-name"
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
Password
|
||||
<input
|
||||
type="password"
|
||||
name="password"
|
||||
placeholder="password"
|
||||
autocomplete="password"
|
||||
/>
|
||||
</label>
|
||||
<input type="hidden" name="client_id" value="{{ .client_id }}"/>
|
||||
<input type="hidden" name="client_secret" value="{{ .client_secret }}"/>
|
||||
<input type="hidden" name="redirect_uri" value="{{ .redirect_uri }}"/>
|
||||
<input type="hidden" name="scope" value="{{ .scope }}"/>
|
||||
</fieldset>
|
||||
|
||||
<input
|
||||
type="submit"
|
||||
value="登录"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user