写点什么

如何搭建一个专属的认证中心(完结篇)

作者:Kevin_913
  • 2023-10-02
    广东
  • 本文字数:1574 字

    阅读完需:约 5 分钟

这一期主要讲解前端如何通过 BFF 层来使用自己的认证中心。


首先说明什么是 BFF 层,BFF 是 Backend For Frontend 的缩写,它主要有几个作用。

1、它可以是有状态的,可以通过 cookie 跟前端交互。

2、可以避免密码信息直接暴露到前端页面。

3、保护后端服务,前端都是暴露到公网的,它对应访问的 api 都是需要公网可以访问的,如果是直接访问后端服务的话,那就需要后端服务暴露到公网,如果有 BFF 这一层,我们只需要暴露 BFF 层到公网,然后在 BFF 层做一个代理到后端的服务。


搭建 BFF 层

BFF 层是一个很轻量的应用,你也可以使用 nodejs 或者其他任何语言来实现,我这里使用的是 golang,这里不会涉及到代理,只涉及如何跟认证中心交互。

1、配置认证中心的信息,这里就会有 clientId 和 clientsecret 的信息。

var (	AppUrl          = "http://localhost:5173/"	MyAuthUrl       = "http://localhost:8000/oauth2/token?grant_type=authorization_code&code=%s&redirect_uri=%s"	RefreshToken    = "http://localhost:8000/oauth2/token?grant_type=refresh_token&refresh_token=%s"	BFFClientId     = "bff"	BFFClientSecret = "bff")
复制代码

2、通过 code 获取 refresh token 和 access token,调用认证中心的 api 的时候需要传入你的 clientId 和 clientSecret,这里可以多做一步就是在服务端缓存 tokens,避免发送重复请求到认证中心,下面是一个通过 code 来获取 refreshtoken 和 accesstoken 的示例。

func RequestToken(c echo.Context) error {
code := c.QueryParams().Get("code") authUrl := fmt.Sprintf(MyAuthUrl, code, AppUrl) req, err := http.NewRequest("POST", authUrl, nil) if err != nil { panic(err) } req.SetBasicAuth(BFFClientId, BFFClientSecret)
client := http.DefaultClient
response, err := client.Do(req) if err != nil { panic(err) } return c.JSON(http.StatusOK, HandleResponse(response))
}
复制代码

3、解析返回的 response 给到前端使用。

func HandleResponse(response *http.Response) map[string]any {	defer response.Body.Close()	b, err := io.ReadAll(response.Body)	if err != nil {		panic(err)	}	var x = map[string]any{}	json.Unmarshal(b, &x)	return x
}
复制代码


前端使用


1、前端判断 localstorage 是否有 refreshtoken,如果没有或者失效,跳转到登录页面重新获取 code 来生成 token。

2、前端拿到 token 后存入到 localstorage。

    async function tokens() {        const { data } = await fetchTokens(code.value)        if (data) {            console.info(data)            if (data.error !== undefined) {                return true            } else {                window.localStorage.setItem("refresh_token", data.refresh_token)                window.localStorage.setItem("access_token", data.access_token)                window.localStorage.setItem("scope", data.scope)                return false            }
}
}
复制代码

3、使用 accesstoken 去获取资源服务器的资源。

export async function userName() {    let accessToken = window.localStorage.getItem("access_token")
return await axios.get("http://localhost:8001/greet2", { headers: { Authorization: "Bearer " + accessToken } }).then(async response => { return response }).catch(response => { console.info(response) return response })}
复制代码


这样整一个流程就完成了,你可以在前端定制化 axios 添加 interceptor 来避免每次都要添加一个 Authorization 的 header。


大家可以动手试试,有问题可以评论区留言。

视频地址:如何搭建一个专属的认证中心(四)完结篇_哔哩哔哩_bilibili

发布于: 刚刚阅读数: 3
用户头像

Kevin_913

关注

纸上得来终觉浅,绝知此事要躬行。 2019-02-25 加入

专注于代码和设计15+年。 主要涉及Java,Golang,云平台。

评论

发布
暂无评论
如何搭建一个专属的认证中心(完结篇)_golang_Kevin_913_InfoQ写作社区