Go实战--golang中OAuth2.0的使用(使用google账号进行登陆验证)
生命不止,继续 go go go!!! 今天继续分享golang中的认证问题,之前写过两篇: 一篇是关于basic认证:Go实战–通过basic认证的http(basic authentication) 一篇是关于JWT的:Go实战–golang中使用JWT(JSON Web Token) 这里就介绍一下golang中使用oauth2.0. OAuth2.0OAuth2.0是OAuth协议的下一版本,但不向后兼容OAuth 1.0即完全废止了OAuth1.0。 OAuth 2.0关注客户端开发者的简易性。要么通过组织在资源拥有者和HTTP服务商之间的被批准的交互动作代表用户,要么允许第三方应用代表用户获得访问的权限。同时为Web应用,桌面应用和手机,和起居室设备提供专门的认证流程。2012年10月,OAuth 2.0协议正式发布为RFC 6749. 在认证和授权的过程中涉及的三方包括: 使用OAuth进行认证和授权的过程如下所示: (A)用户打开客户端以后,客户端要求用户给予授权。 更详细的内容,可以参考:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html package oauth2Package oauth2 provides support for making OAuth2 authorized and authenticated HTTP requests. It can additionally grant authorization with Bearer JWT. 获取: go get golang.org/x/oauth2
type Config type Config struct {
// ClientID is the application's ID.
ClientID string
// ClientSecret is the application's secret.
ClientSecret string
// Endpoint contains the resource server's token endpoint
// URLs. These are constants specific to each server and are
// often available via site-specific packages,such as
// google.Endpoint or github.Endpoint.
Endpoint Endpoint
// RedirectURL is the URL to redirect users going through
// the OAuth flow,after the resource owner's URLs.
RedirectURL string
// Scope specifies optional requested permissions.
Scopes []string
}
func (*Config) AuthCodeURL func (c *Config) AuthCodeURL(state string,opts ...AuthCodeOption) string
AuthCodeURL returns a URL to OAuth 2.0 provider’s consent page that asks for permissions for the required scopes explicitly. func (*Config) Exchange func (c *Config) Exchange(ctx context.Context,code string) (*Token,error)
Exchange converts an authorization code into a token. type Endpoint type Endpoint struct {
AuthURL string
TokenURL string
}
Endpoint contains the OAuth 2.0 provider’s authorization and token endpoint URLs. 使用google账号进行登陆验证1.去Google Cloud Platform,创建一个项目 2.凭据,创建凭据,选择OAuth客户端ID 3. 4.记录下客户端ID和客户端密钥 编码 package main
import (
"fmt"
"io/ioutil"
"net/http"
"golang.org/x/oauth2"
)
const htmlIndex = `<html><body> <a href="/GoogleLogin">Log in with Google</a> </body></html> `
var endpotin = oauth2.Endpoint{
AuthURL: "https://accounts.google.com/o/oauth2/auth",TokenURL: "https://accounts.google.com/o/oauth2/token",}
var googleOauthConfig = &oauth2.Config{
ClientID: "your_client_id",ClientSecret: "your_client_secret",RedirectURL: "http://localhost:8000/GoogleCallback",Scopes: []string{"https://www.googleapis.com/auth/userinfo.profile","https://www.googleapis.com/auth/userinfo.email"},Endpoint: endpotin,}
const oauthStateString = "random"
func main() {
http.HandleFunc("/",handleMain)
http.HandleFunc("/GoogleLogin",handleGoogleLogin)
http.HandleFunc("/GoogleCallback",handleGoogleCallback)
fmt.Println(http.ListenAndServe(":8000",nil))
}
func handleMain(w http.ResponseWriter,r *http.Request) {
fmt.Fprintf(w,htmlIndex)
}
func handleGoogleLogin(w http.ResponseWriter,r *http.Request) {
url := googleOauthConfig.AuthCodeURL(oauthStateString)
fmt.Println(url)
http.Redirect(w,r,url,http.StatusTemporaryRedirect)
}
func handleGoogleCallback(w http.ResponseWriter,r *http.Request) {
state := r.FormValue("state")
if state != oauthStateString {
fmt.Printf("invalid oauth state,expected '%s',got '%s'n",oauthStateString,state)
http.Redirect(w,"/",http.StatusTemporaryRedirect)
return
}
fmt.Println(state)
code := r.FormValue("code")
fmt.Println(code)
token,err := googleOauthConfig.Exchange(oauth2.NoContext,code)
fmt.Println(token)
if err != nil {
fmt.Println("Code exchange failed with '%s'n",err)
http.Redirect(w,http.StatusTemporaryRedirect)
return
}
response,err := http.Get("https://www.googleapis.com/oauth2/v2/userinfo?access_token=" + token.AccessToken)
defer response.Body.Close()
contents,err := ioutil.ReadAll(response.Body)
fmt.Fprintf(w,"Content: %sn",contents)
}
把ClientID和ClientSecret换成你自己的!!! 浏览器访问:http://localhost:8000 点击Log in with Google 结果: Content: {
"id": "114512230444013345330","email": "wangshubo1989@126.com","verified_email": true,"name": "王书博","given_name": "书博","family_name": "王","picture": "https://lh3.googleusercontent.com/-XdUIqdMkCWA/AAAAAAAAAAI/AAAAAAAAAAA/4252rscbv5M/photo.jpg","locale": "zh-CN"
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |