Skip to content

Instantly share code, notes, and snippets.

@suapapa
Last active August 10, 2018 05:07
Show Gist options
  • Save suapapa/7040b167e58b0af3daedde22ebafdbd7 to your computer and use it in GitHub Desktop.
Save suapapa/7040b167e58b0af3daedde22ebafdbd7 to your computer and use it in GitHub Desktop.
<html>
<head></head>
<body>
<a href="{{ . }}">Kakao Login</a>
</body>
</html>
package main
import (
"crypto/rand"
"encoding/base64"
"html/template"
"io/ioutil"
"log"
"net/http"
"os"
"github.com/gorilla/sessions"
"golang.org/x/oauth2"
"golang.org/x/oauth2/kakao"
)
type user struct {
Name string `json:"name"`
Email string `json:"email"`
}
const (
callbackURL = "http://localhost:1333/auth/callback"
kakaoUserInfoAPIEndpoint = "https://kapi.kakao.com/v2/user/me"
)
var (
kakaoOAuthConf *oauth2.Config
store = sessions.NewCookieStore([]byte("secret"))
)
func init() {
kakaoOAuthConf = &oauth2.Config{
ClientID: os.Getenv("KAKAO_CLIENT_ID"),
// ClientSecret: os.Getenv("KAKAO_CLIENT_SECRET"),
RedirectURL: callbackURL,
Endpoint: kakao.Endpoint,
}
}
func main() {
http.HandleFunc("/", handleMain)
http.HandleFunc("/auth", handleAuth)
http.HandleFunc("/auth/callback", handleAuthCallback)
log.Fatal(http.ListenAndServe(":1333", nil))
}
func handleMain(w http.ResponseWriter, r *http.Request) {
renderTemplate(w, "main.html", nil)
}
func handleAuth(w http.ResponseWriter, r *http.Request) {
session, _ := store.Get(r, "session")
session.Options = &sessions.Options{
Path: "/auth",
MaxAge: 300,
}
state := randToken()
session.Values["state"] = state
session.Save(r, w)
renderTemplate(w, "auth.html", kakaoOAuthConf.AuthCodeURL(state))
}
func handleAuthCallback(w http.ResponseWriter, r *http.Request) {
session, _ := store.Get(r, "session")
state := session.Values["state"]
delete(session.Values, "state")
session.Save(r, w)
if state != r.FormValue("state") {
http.Error(w, "Invalid session state", http.StatusUnauthorized)
return
}
// kakao needs addtional params, client_id and redirect_uri to exchange token
token, err := kakaoOAuthConf.Exchange(
oauth2.NoContext,
r.FormValue("code"),
oauth2.SetAuthURLParam("client_id", os.Getenv("KAKAO_CLIENT_ID")),
oauth2.SetAuthURLParam("redirect_uri", callbackURL),
)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
client := kakaoOAuthConf.Client(oauth2.NoContext, token)
userInfoResp, err := client.Get(kakaoUserInfoAPIEndpoint)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
defer userInfoResp.Body.Close()
userInfo, err := ioutil.ReadAll(userInfoResp.Body)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
log.Println(string(userInfo))
// var authUser user
// json.Unmarshal(userInfo, &authUser)
// log.Println(authUser)
// session.Options = &sessions.Options{
// Path: "/",
// MaxAge: 86400, // 1 day
// }
// session.Values["user"] = authUser.Email
// session.Values["username"] = authUser.Name
// session.Save(r, w)
http.Redirect(w, r, "/", http.StatusFound)
}
func randToken() string {
b := make([]byte, 32)
rand.Read(b)
return base64.StdEncoding.EncodeToString(b)
}
func renderTemplate(w http.ResponseWriter, name string, data interface{}) {
tmpl, _ := template.ParseFiles(name)
tmpl.Execute(w, data)
}
<html>
<head></head>
<body>
<a href="/auth">Sign In</a>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment