天天看點

go-OAuth2.0

注冊

在https://github.com/settings/applications/new 注冊一個應用,擷取clientId 和  client secrets

go-OAuth2.0
go-OAuth2.0

通過github進行授權

前段頁面 通路:

<a href="https://github.com/login/oauth/authorize?client_id=e511f4733c56d5487d5d&redirect_uri=http://localhost:8087/oauth/redirect" target="_blank" rel="external nofollow" >
    Login by GitHub
</a>
      

跳轉到github的授權頁面 确認授權,回調/oauth/redirect 通過傳遞參數code

(注意 href 的 redirect_uri 必須是在github上配置的 callback URL 比對,否則調用callback URL的時候不會傳遞code,提示錯誤。

關于redirect_uri  ,這個redirect_uri 作為參數傳遞給githhub服務,github 會調用這個redirect_uri 

redirect_uri 必須是和application上配置Authorization callback URL 一樣活着是它的子域名下。詳見:https://docs.github.com/en/developers/apps/building-oauth-apps/authorizing-oauth-apps#redirect-urls)

正常:

go-OAuth2.0

錯誤:

go-OAuth2.0

 錯誤資訊:/oauth/redirect?error=redirect_uri_mismatch&error_description=The+redirect_uri+MUST+match+the+registered+callback+URL+for+this+application.&error_uri=https%3A%2F%2Fdocs.github.com%2Fapps%2Fmanaging-oauth-apps%2Ftroubleshooting-authorization-request-errors%2F%23redirect-uri-mismatch

回調伺服器端接口

伺服器端拿到這個code之後調用接口https://github.com/login/oauth/access_token?" +

            "client_id=%s&client_secret=%s&code=%s  擷取accessToken。然後重定向到某個頁面

w.Header().Set("Location", "/hello.html?access_token="+t.AccessToken) 講token帶上。

http.HandleFunc("/oauth/redirect", func(w http.ResponseWriter, r *http.Request) {
		err := r.ParseForm()
		if err != nil {
			fmt.Fprintf(os.Stdout, "could not parse query: %v", err)
			w.WriteHeader(http.StatusBadRequest)
		}
		code := r.FormValue("code")

		reqURL := fmt.Sprintf("https://github.com/login/oauth/access_token?" +
			"client_id=%s&client_secret=%s&code=%s", clientID, clientSecret, code)
		req, err := http.NewRequest(http.MethodPost, reqURL, nil)
		if err != nil {
			fmt.Fprintf(os.Stdout, "could not create HTTP request: %v", err)
			w.WriteHeader(http.StatusBadRequest)
		}
		req.Header.Set("accept", "application/json")

		res, err := httpClient.Do(req)
		if err != nil {
			fmt.Fprintf(os.Stdout, "could not send HTTP request: %v", err)
			w.WriteHeader(http.StatusInternalServerError)
		}
		defer res.Body.Close()

		var t AccessTokenResponse
		if err := json.NewDecoder(res.Body).Decode(&t); err != nil {
			fmt.Fprintf(os.Stdout, "could not parse JSON response: %v", err)
			w.WriteHeader(http.StatusBadRequest)
		}

		w.Header().Set("Location", "/hello.html?access_token="+t.AccessToken)
		w.WriteHeader(http.StatusFound)
	})
           

拿到這個token之後,就可以調用github的使用者資訊接口:

頁面上調用

// 擷取access_token
    const token = getQueryVariable("access_token");
    // 調用使用者資訊接口
    fetch('https://api.github.com/user', {
        headers: {
            Authorization: 'token ' + token
        }
    })
    // 解析請求的JSON
     .then(res => res.json())
     .then(res => {
        // 傳回使用者資訊
        const nameNode = document.createTextNode(`Hi, ${res.login}, Welcome to login our site by GitHub!`)
        document.body.appendChild(nameNode)
     })
           
go-OAuth2.0

 restclient 調用列印結果

go-OAuth2.0

傳回json格式的資料

{
  "login": "xiaojianlee",
  "id": 12822795,
  "node_id": "MDQ6VXNlcjEyODIyNzk1",
  "avatar_url": "https://avatars.githubusercontent.com/u/12822795?v=4",
  "gravatar_id": "",
  "url": "https://api.github.com/users/xiaojianlee",
  "html_url": "https://github.com/xiaojianlee",
  "followers_url": "https://api.github.com/users/xiaojianlee/followers",
  "following_url": "https://api.github.com/users/xiaojianlee/following{/other_user}",
  "gists_url": "https://api.github.com/users/xiaojianlee/gists{/gist_id}",
  "starred_url": "https://api.github.com/users/xiaojianlee/starred{/owner}{/repo}",
  "subscriptions_url": "https://api.github.com/users/xiaojianlee/subscriptions",
  "organizations_url": "https://api.github.com/users/xiaojianlee/orgs",
  "repos_url": "https://api.github.com/users/xiaojianlee/repos",
  "events_url": "https://api.github.com/users/xiaojianlee/events{/privacy}",
  "received_events_url": "https://api.github.com/users/xiaojianlee/received_events",
  "type": "User",
  "site_admin": false,
  "name": null,
  "company": null,
  "blog": "",
  "location": null,
  "email": null,
  "hireable": null,
  "bio": null,
  "twitter_username": null,
  "public_repos": 7,
  "public_gists": 0,
  "followers": 0,
  "following": 0,
  "created_at": "2015-06-10T02:00:52Z",
  "updated_at": "2021-06-29T13:39:15Z"
}