GitHub OAuth Authentication Vuejs and Golang
This article will teach you how to integrate GitHub OAuth Authentication into your Vue.js, MongoDB, and Golang applications.
Also, after the user is authenticated, we will generate and return JSON Web Tokens to the user’s browser or client as HTTPOnly cookies.
Vue.js, MongoDB, and Golang Series:
- GitHub OAuth Authentication Vuejs, MongoDB and Golang
- Google OAuth Authentication Vue.js and Node.js (No Passport)
- GitHub OAuth Authentication Vue.js and Node.js (No Passport)
Related Articles:
- Google OAuth Authentication React.js and Node.js(No Passport)
- GitHub OAuth Authentication React.js and Node.js(No Passport)
- How to Implement GitHub OAuth in React.js
- How to Implement Google OAuth2 in React.js

Prerequisites
- Fundamental knowledge of HTML, CSS, Vue.js, and Golang is required.
- Must have Golang installed on your computer.
Create a New OAuth App on GitHub
To begin, sign in to yourGitHub account. At the top-right corner, click on your profile and select“Settings” from the dropdown menu.
On the profile settings page, scroll down and click on“Developer settings” from the left sidebar.

Next, on the Developer settings screen selectOAuth Apps and click on the“New OAuth App” button on the right side.

Now, provide the required data needed for the OAuth app and click on the“Register application” button.
The authorization callback URL should be a route on the Golang server. It’s similar to theGoogle OAuth integration in the previous article.

After GitHub has registered the OAuth app, click on the“Generate a new client secret” button to generate the client secret key.
For security reasons, GitHub might redirect you to provide your password again so don’t freak out.

Open the.env
file in your server folder and add the generated client secret, client ID, and the authorized callback URL.
.env
GITHUB_OAUTH_CLIENT_ID=your client Id hereGITHUB_OAUTH_CLIENT_SECRET=your client secret hereGITHUB_OAUTH_REDIRECT_URL=http://localhost:8000/api/sessions/oauth/github
Also, don’t forget to add the credentials to the.env.local
file in the Vue.js app.
VITE_GITHUB_OAUTH_CLIENT_ID=your client Id hereVITE_GITHUB_OAUTH_CLIENT_SECRET=your client secret hereVITE_GITHUB_OAUTH_REDIRECT_URL=http://localhost:8000/api/sessions/oauth/github
Note: use
Vue_App_
prefix if you created the Vue.js app with the@vue/cli
.
Generate the Consent Screen URI in Vue.js
Now that we have acquired the necessary credentials, we are now ready to implement the GitHub OAuth in our Vue.js application.
To begin, we need to create a helper function to generate the GitHub OAuth consent screen URL using the client ID, the selected scopes, and the authorization callback URL.
Adding the scopes to the consent screen URL will instruct GitHub to grant us read access to the resources listed in the scopes.
You canread more about the various scopes you can add on the GitHub OAuth official documentation.
src/utils/getGithubUrl.js
export function getGitHubUrl(from) { const rootURl = 'https://github.com/login/oauth/authorize'; const options = { client_id: import.meta.env.VITE_GITHUB_OAUTH_CLIENT_ID, redirect_uri: import.meta.env.VITE_GITHUB_OAUTH_REDIRECT_URL, scope: 'user:email', state: from, }; const qs = new URLSearchParams(options); return `${rootURl}?${qs.toString()}`;}
Create a Simple GitHub OAuth Button with Vue.js
Now, let’s create a simple GitHub OAuth button with Vue.js and bindgetGitHubUrl(from)
to thehref
.

src/App.vue
<script setup>import GoogleLogo from './assets/google.svg';import GitHubLogo from './assets/github.svg';import { getGoogleUrl } from './utils/getGoogleUrl';import { getGitHubUrl } from './utils/getGitHubUrl';const from = '/';</script><template> <div class="container"> <div class="social-auth"> <!-- Google OAuth --> <a :href="getGoogleUrl(from)" class="auth-btn google-auth"> <img :src="GoogleLogo" alt="Google Logo" /> <span>Google</span> </a> <!-- GitHub OAuth --> <a :href="getGitHubUrl(from)" class="auth-btn github-auth"> <img :src="GitHubLogo" alt="GitHub Logo" /> <span>Google</span> </a> </div> </div></template><style>* { margin: 0; padding: 0; box-sizing: border-box;}a { text-decoration: none; color: inherit;}html { font-size: 62.5%;}body { font-family: Roboto, sans-serif; color: #222; font-size: 1.6rem;}.container { background-color: #2363eb; height: 100vh; width: 100vw; display: flex; align-items: center; justify-content: center;}.social-auth { max-width: 27rem; width: 100%; display: flex; align-items: center; flex-direction: column;}.auth-btn { background-color: #fff; border-radius: 5px; padding: 0.6rem 0; width: 100%; display: flex; align-items: center; justify-content: center; transition: all 0.3s ease-in-out;}.auth-btn img { height: 4rem; margin-right: 1rem;}.auth-btn span { font-size: 1.8rem;}.auth-btn:hover { box-shadow: 0 1px 13px 0 rgb(0 0 0 / 15%);}.auth-btn.google-auth { margin-bottom: 1.5rem;}</style>
Now when you click on the GitHub OAuth button, you will be redirected to the consent screen where you can click on the green authorize button assuming you’ve already logged into your GitHub account. Otherwise, you will need to provide your email and password.

After signing in with your email and password or when you click on the authorize button, aGET request will be made to the Golang server. The server should return a404 errorassuming it is running.
The most exciting part of the authorized callback URL is the code in the query string. Later, we’ll make aPOSTrequest with the code on the server to obtain an access token.

Implement the GitHub OAuth in Golang and MongoDB
Now open theconfig/default.go
file and add the generated GitHub OAuth client ID, client secret, the Vue.js origin URL, and the authorized callback URL to the Config struct.
Including the environment variables in the Config struct will enable theViper package to load and make them available in the project.
go get github.com/spf13/viper
config/default.go
type Config struct {DBUri string `mapstructure:"MONGODB_LOCAL_URI"`RedisUri string `mapstructure:"REDIS_URL"`Port string `mapstructure:"PORT"`ClientOrigin string `mapstructure:"CLIENT_ORIGIN"`AccessTokenPrivateKey string `mapstructure:"ACCESS_TOKEN_PRIVATE_KEY"`AccessTokenPublicKey string `mapstructure:"ACCESS_TOKEN_PUBLIC_KEY"`RefreshTokenPrivateKey string `mapstructure:"REFRESH_TOKEN_PRIVATE_KEY"`RefreshTokenPublicKey string `mapstructure:"REFRESH_TOKEN_PUBLIC_KEY"`AccessTokenExpiresIn time.Duration `mapstructure:"ACCESS_TOKEN_EXPIRED_IN"`RefreshTokenExpiresIn time.Duration `mapstructure:"REFRESH_TOKEN_EXPIRED_IN"`AccessTokenMaxAge int `mapstructure:"ACCESS_TOKEN_MAXAGE"`RefreshTokenMaxAge int `mapstructure:"REFRESH_TOKEN_MAXAGE"`GoogleClientID string `mapstructure:"GOOGLE_OAUTH_CLIENT_ID"`GoogleClientSecret string `mapstructure:"GOOGLE_OAUTH_CLIENT_SECRET"`GoogleOAuthRedirectUrl string `mapstructure:"GOOGLE_OAUTH_REDIRECT_URL"`GitHubClientID string `mapstructure:"GITHUB_OAUTH_CLIENT_ID"`GitHubClientSecret string `mapstructure:"GITHUB_OAUTH_CLIENT_SECRET"`GitHubOAuthRedirectUrl string `mapstructure:"GITHUB_OAUTH_REDIRECT_URL"`}func LoadConfig(path string) (config Config, err error) {viper.AddConfigPath(path)viper.SetConfigType("env")viper.SetConfigName("app")viper.AutomaticEnv()err = viper.ReadInConfig()if err != nil {return}err = viper.Unmarshal(&config)return}
Get the GitHub OAuth Access Token and User’s Credentials
Now let’s create autils/githubOAuth.go
file in the root directory and add these two functions:
GetGitHubOauthToken()
– Makes aPOST request to retrieve the OAuth access token from GitHub.GetGitHubUser()
– Makes aGET request with the access token to obtain the user’s profile information.
utils/githubOAuth.go
type GitHubOauthToken struct {Access_token string}type GitHubUserResult struct {Name stringPhoto stringEmail string}func GetGitHubOauthToken(code string) (*GitHubOauthToken, error) {const rootURl = "https://github.com/login/oauth/access_token"config, _ := config.LoadConfig(".")values := url.Values{}values.Add("code", code)values.Add("client_id", config.GitHubClientID)values.Add("client_secret", config.GitHubClientSecret)query := values.Encode()queryString := fmt.Sprintf("%s?%s", rootURl, bytes.NewBufferString(query))req, err := http.NewRequest("POST", queryString, nil)if err != nil {return nil, err}req.Header.Set("Content-Type", "application/x-www-form-urlencoded")client := http.Client{Timeout: time.Second * 30,}res, err := client.Do(req)if err != nil {return nil, err}if res.StatusCode != http.StatusOK {return nil, errors.New("could not retrieve token")}resBody, err := ioutil.ReadAll(res.Body)if err != nil {return nil, err}parsedQuery, err := url.ParseQuery(string(resBody))if err != nil {return nil, err}tokenBody := &GitHubOauthToken{Access_token: parsedQuery["access_token"][0],}return tokenBody, nil}func GetGitHubUser(access_token string) (*GitHubUserResult, error) {rootUrl := "https://api.github.com/user"req, err := http.NewRequest("GET", rootUrl, nil)if err != nil {return nil, err}req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", access_token))client := http.Client{Timeout: time.Second * 30,}res, err := client.Do(req)if err != nil {return nil, err}if res.StatusCode != http.StatusOK {return nil, errors.New("could not retrieve user")}resBody, err := ioutil.ReadAll(res.Body)if err != nil {return nil, err}var GitHubUserRes map[string]interface{}if err := json.Unmarshal(resBody, &GitHubUserRes); err != nil {return nil, err}userBody := &GitHubUserResult{Email: GitHubUserRes["email"].(string),Name: GitHubUserRes["login"].(string),Photo: GitHubUserRes["avatar_url"].(string),}return userBody, nil}
Update the User Structs
If you are coming from a previous article in this series then update the user structs in themodels/user.model.go
file to have thePhoto
andProvider
fields.
The logic here is when a user creates an account using GitHub OAuth, theprovider
field will be set toGitHub
. However, a user who registers the account with email and password will have theprovider
field set tolocal
.
models/user.model.ts
type SignUpInput struct {Name string `json:"name" bson:"name" binding:"required"`Email string `json:"email" bson:"email" binding:"required"`Password string `json:"password" bson:"password" binding:"required,min=8"`PasswordConfirm string `json:"passwordConfirm" bson:"passwordConfirm,omitempty" binding:"required"`Role string `json:"role" bson:"role"`Provider string `json:"provider,omitempty" bson:"provider,omitempty"`Photo string `json:"photo,omitempty" bson:"photo,omitempty"`Verified bool `json:"verified" bson:"verified"`CreatedAt time.Time `json:"created_at" bson:"created_at"`UpdatedAt time.Time `json:"updated_at" bson:"updated_at"`}type SignInInput struct {Email string `json:"email" bson:"email" binding:"required"`Password string `json:"password" bson:"password" binding:"required"`}type DBResponse struct {ID primitive.ObjectID `json:"id" bson:"_id"`Name string `json:"name" bson:"name"`Email string `json:"email" bson:"email"`Password string `json:"password" bson:"password"`PasswordConfirm string `json:"passwordConfirm,omitempty" bson:"passwordConfirm,omitempty"`Provider string `json:"provider" bson:"provider"`Photo string `json:"photo,omitempty" bson:"photo,omitempty"`Role string `json:"role" bson:"role"`Verified bool `json:"verified" bson:"verified"`CreatedAt time.Time `json:"created_at" bson:"created_at"`UpdatedAt time.Time `json:"updated_at" bson:"updated_at"`}type UserResponse struct {ID primitive.ObjectID `json:"id,omitempty" bson:"_id,omitempty"`Name string `json:"name,omitempty" bson:"name,omitempty"`Email string `json:"email,omitempty" bson:"email,omitempty"`Role string `json:"role,omitempty" bson:"role,omitempty"`Photo string `json:"photo,omitempty" bson:"photo,omitempty"`Provider string `json:"provider" bson:"provider"`CreatedAt time.Time `json:"created_at" bson:"created_at"`UpdatedAt time.Time `json:"updated_at" bson:"updated_at"`}type UpdateDBUser struct {ID primitive.ObjectID `json:"id,omitempty" bson:"_id,omitempty"`Name string `json:"name,omitempty" bson:"name,omitempty"`Email string `json:"email,omitempty" bson:"email,omitempty"`Password string `json:"password,omitempty" bson:"password,omitempty"`PasswordConfirm string `json:"passwordConfirm,omitempty" bson:"passwordConfirm,omitempty"`Role string `json:"role,omitempty" bson:"role,omitempty"`Provider string `json:"provider" bson:"provider"`Photo string `json:"photo,omitempty" bson:"photo,omitempty"`Verified bool `json:"verified,omitempty" bson:"verified,omitempty"`CreatedAt time.Time `json:"created_at,omitempty" bson:"created_at,omitempty"`UpdatedAt time.Time `json:"updated_at,omitempty" bson:"updated_at,omitempty"`}func FilteredResponse(user *DBResponse) UserResponse {return UserResponse{ID: user.ID,Email: user.Email,Name: user.Name,Role: user.Role,Provider: user.Provider,Photo: user.Photo,CreatedAt: user.CreatedAt,UpdatedAt: user.UpdatedAt,}}
Add a Service to Upsert the User Document
Before we start working on the service, let’s create a helper function to marshal and unmarshal the struct into a BSON document.
utils/helper.go
func ToDoc(v interface{}) (doc *bson.D, err error) {data, err := bson.Marshal(v)if err != nil {return}err = bson.Unmarshal(data, &doc)return}
Now open theservices/user.service.go
file and add anUpsertUser
method to theUserService
interface. The purpose of theUpsertUser
service is to access and mutate the MongoDB database.
services/user.service.go
type UserService interface {FindUserById(string) (*models.DBResponse, error)FindUserByEmail(string) (*models.DBResponse, error)UpsertUser(string, *models.UpdateDBUser) (*models.DBResponse, error)}
Next, add the following code to theservices/user.service.impl.go
file. TheUpsertUser
function receiver will contain the logic to upsert the user’s credentials in the MongoDB database.
services/user.service.impl.go
type UserServiceImpl struct {collection *mongo.Collectionctx context.Context}func NewUserServiceImpl(collection *mongo.Collection, ctx context.Context) UserService {return &UserServiceImpl{collection, ctx}}// FindUserByID// FindUserByEmail// UpsertUserfunc (uc *UserServiceImpl) UpsertUser(email string, data *models.UpdateDBUser) (*models.DBResponse, error) {doc, err := utils.ToDoc(data)if err != nil {return nil, err}opts := options.FindOneAndUpdate().SetUpsert(true).SetReturnDocument(1)query := bson.D{{Key: "email", Value: email}}update := bson.D{{Key: "$set", Value: doc}}res := uc.collection.FindOneAndUpdate(uc.ctx, query, update, opts)var updatedPost *models.DBResponseif err := res.Decode(&updatedPost); err != nil {return nil, errors.New("no post with that Id exists")}return updatedPost, nil}
If you carefully take a look at the code above you’ll notice that we used.SetUpsert(true)
on theFindOneAndUpdateOptions instance returned by callingoptions.FindOneAndUpdate()
.
Including.SetUpsert(true)
will tell MongoDB to create a new user document if the email specified in the BSON query does not exist in the database whereas MongoDB will only update the user document if that email already exists.
Create the GitHub OAuth Handler
To begin, we need to install theGolang JWT package to enable us to generate the JSON Web Tokens.
The current version of theGolang JWT package isv4 but this might change in the future so navigate to theirGitHub page to install the recent version.
go get -u github.com/golang-jwt/jwt/v4
Now let’s create two utility functions to generate and verify the access and refresh tokens.
utils/token.go
func CreateToken(ttl time.Duration, payload interface{}, privateKey string) (string, error) {decodedPrivateKey, err := base64.StdEncoding.DecodeString(privateKey)if err != nil {return "", fmt.Errorf("could not decode key: %w", err)}key, err := jwt.ParseRSAPrivateKeyFromPEM(decodedPrivateKey)if err != nil {return "", fmt.Errorf("create: parse key: %w", err)}now := time.Now().UTC()claims := make(jwt.MapClaims)claims["sub"] = payloadclaims["exp"] = now.Add(ttl).Unix()claims["iat"] = now.Unix()claims["nbf"] = now.Unix()token, err := jwt.NewWithClaims(jwt.SigningMethodRS256, claims).SignedString(key)if err != nil {return "", fmt.Errorf("create: sign token: %w", err)}return token, nil}func ValidateToken(token string, publicKey string) (interface{}, error) {decodedPublicKey, err := base64.StdEncoding.DecodeString(publicKey)if err != nil {return nil, fmt.Errorf("could not decode: %w", err)}key, err := jwt.ParseRSAPublicKeyFromPEM(decodedPublicKey)if err != nil {return "", fmt.Errorf("validate: parse key: %w", err)}parsedToken, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) {if _, ok := t.Method.(*jwt.SigningMethodRSA); !ok {return nil, fmt.Errorf("unexpected method: %s", t.Header["alg"])}return key, nil})if err != nil {return nil, fmt.Errorf("validate: %w", err)}claims, ok := parsedToken.Claims.(jwt.MapClaims)if !ok || !parsedToken.Valid {return nil, fmt.Errorf("validate: invalid token")}return claims["sub"], nil}
Next, let’s add theGitHubOAuth
controller to thecontrollers/auth.controller.go
file. This handler will be evoked to authenticate the user when GitHub redirects them to the server.
controllers/auth.controller.ts
type AuthController struct {authService services.AuthServiceuserService services.UserService}func NewAuthController(authService services.AuthService, userService services.UserService) AuthController {return AuthController{authService, userService}}// SignUp User// SignIn User// Refresh Access Token//Google OAuth// GitHub OAuthfunc (ac *AuthController) GitHubOAuth(ctx *gin.Context) {code := ctx.Query("code")var pathUrl string = "/"if ctx.Query("state") != "" {pathUrl = ctx.Query("state")}if code == "" {ctx.JSON(http.StatusUnauthorized, gin.H{"status": "fail", "message": "Authorization code not provided!"})return}// Use the code to get the id and access tokenstokenRes, err := utils.GetGitHubOauthToken(code)if err != nil {ctx.JSON(http.StatusBadGateway, gin.H{"status": "fail", "message": err.Error()})}user, err := utils.GetGitHubUser(tokenRes.Access_token)if err != nil {ctx.JSON(http.StatusBadGateway, gin.H{"status": "fail", "message": err.Error()})}createdAt := time.Now()resBody := &models.UpdateDBUser{Email: user.Email,Name: user.Name,Photo: user.Photo,Provider: "github",Role: "user",Verified: true,CreatedAt: createdAt,UpdatedAt: createdAt,}updatedUser, err := ac.userService.UpsertUser(user.Email, resBody)if err != nil {ctx.JSON(http.StatusBadGateway, gin.H{"status": "fail", "message": err.Error()})}config, _ := config.LoadConfig(".")// Generate Tokensaccess_token, err := utils.CreateToken(config.AccessTokenExpiresIn, updatedUser.ID.Hex(), config.AccessTokenPrivateKey)if err != nil {ctx.JSON(http.StatusBadRequest, gin.H{"status": "fail", "message": err.Error()})return}refresh_token, err := utils.CreateToken(config.RefreshTokenExpiresIn, updatedUser.ID.Hex(), config.RefreshTokenPrivateKey)if err != nil {ctx.JSON(http.StatusBadRequest, gin.H{"status": "fail", "message": err.Error()})return}ctx.SetCookie("access_token", access_token, config.AccessTokenMaxAge*60, "/", "localhost", false, true)ctx.SetCookie("refresh_token", refresh_token, config.RefreshTokenMaxAge*60, "/", "localhost", false, true)ctx.SetCookie("logged_in", "true", config.AccessTokenMaxAge*60, "/", "localhost", false, false)ctx.Redirect(http.StatusTemporaryRedirect, fmt.Sprint(config.ClientOrigin, pathUrl))}
Define the GitHub OAuth Route
Next, let’s add the GitHub OAuth route to theroutes/session.routes.go
file.
routes/session.routes.go
type SessionRouteController struct {authController controllers.AuthController}func NewSessionRouteController(authController controllers.AuthController) SessionRouteController {return SessionRouteController{authController}}func (rc *SessionRouteController) SessionRoute(rg *gin.RouterGroup) {router := rg.Group("/sessions/oauth")router.GET("/google", rc.authController.GoogleOAuth) router.GET("/github", rc.authController.GitHubOAuth)}
Register the Session Router
Now in themain.go
file, instantiate the router constructor function, and add it to theGin Gonic middleware stack.
We also need to install thecors package and include it in the middleware stack to enable us to accept requests from the Vue.js app.
var (server *gin.Enginectx context.Contextmongoclient *mongo.Clientredisclient *redis.ClientuserService services.UserServiceUserController controllers.UserControllerUserRouteController routes.UserRouteControllerauthCollection *mongo.CollectionauthService services.AuthServiceAuthController controllers.AuthControllerAuthRouteController routes.AuthRouteControllerSessionRouteController routes.SessionRouteController)func init() {config, err := config.LoadConfig(".")if err != nil {log.Fatal("Could not load environment variables", err)}ctx = context.TODO()// Connect to MongoDBmongoconn := options.Client().ApplyURI(config.DBUri)mongoclient, err := mongo.Connect(ctx, mongoconn)if err != nil {panic(err)}if err := mongoclient.Ping(ctx, readpref.Primary()); err != nil {panic(err)}fmt.Println("MongoDB successfully connected...")// Connect to Redisredisclient = redis.NewClient(&redis.Options{Addr: config.RedisUri,})if _, err := redisclient.Ping(ctx).Result(); err != nil {panic(err)}err = redisclient.Set(ctx, "test", "Welcome to Golang with Redis and MongoDB", 0).Err()if err != nil {panic(err)}fmt.Println("Redis client connected successfully...")// CollectionsauthCollection = mongoclient.Database("golang_mongodb").Collection("users")userService = services.NewUserServiceImpl(authCollection, ctx)authService = services.NewAuthService(authCollection, ctx)AuthController = controllers.NewAuthController(authService, userService)AuthRouteController = routes.NewAuthRouteController(AuthController)SessionRouteController = routes.NewSessionRouteController(AuthController)UserController = controllers.NewUserController(userService)UserRouteController = routes.NewRouteUserController(UserController)server = gin.Default()}func main() {config, err := config.LoadConfig(".")if err != nil {log.Fatal("Could not load config", err)}defer mongoclient.Disconnect(ctx)value, err := redisclient.Get(ctx, "test").Result()if err == redis.Nil {fmt.Println("key: test does not exist")} else if err != nil {panic(err)}corsConfig := cors.DefaultConfig()corsConfig.AllowOrigins = []string{"http://localhost:8000", "http://localhost:3000"}corsConfig.AllowCredentials = trueserver.Use(cors.New(corsConfig))router := server.Group("/api")router.GET("/healthchecker", func(ctx *gin.Context) {ctx.JSON(http.StatusOK, gin.H{"status": "success", "message": value})})AuthRouteController.AuthRoute(router)UserRouteController.UserRoute(router, userService)SessionRouteController.SessionRoute(router)log.Fatal(server.Run(":" + config.Port))}
Conclusion
Congratulations on reaching the end. In this article, you learned how to integrate GitHub OAuth Authentication in your Vue.js, Golang,Gin Gonic, and MongoDB applications.
Check out the source code here:
Google OAuth Authentication With Vue.js and Golang
React Query, and Axios Interceptors JWT Authentication
2 Comments
- Jameson December 3, 2022Reply
Thanks for the walkthrough on how you do OAuth2 with Golang and Vue. It’s been good to see a full, working example. A few things jumped out at me that I wanted to get clarification on.
1. Golang has a great `oauth2` library that can replace a lot of the code you wrote around the OAuth2 flow.
2. It does not appear you are doing anything with the `state` value other than setting it to `/`. This is leaving things vulnerable to CSRF attacks, at least per Auth0 (https://auth0.com/docs/secure/attack-protection/state-parameters).
3. You’re getting the an access token and refresh token back from GitHub and promptly disregarding it after you load the user via GitHub’s API. You’re then generating your own access and refresh tokens. This doesn’t seem correct to me, as you’ve now basically disconnected your user from the GitHub user, meaning if they revoke access to your application, it will have no effect. Should the access and refresh tokens from GitHub by put into the JWT token? If the front end then makes a request to the backend and its access token is expired, you make a call to GitHub’s API to refresh it?
- Edemon December 4, 2022Reply
By the way, thanks for the detailed analysis.
1. I knew there was anoauth2 library in Golang that I could have used to make my life easier but the implementation is not that complex that’s why I decided to write the logic myself. Also, theoauth2 library has a similar implementation under the hood.
2. The primary purpose of thestate parameter is to mitigate CSRF attacks. My intention was to redirect the user to a protected page after the authentication finishes. Let’s say a user attempted to access his account details which is a protected page but since he wasn’t logged in, he was redirected to the login page. Before the redirect, we’ll store the path he was trying to access in the
const from = 'path_user_tried_to-access'
variable and add it to the state parameter so that the Golang server will redirect the user to the path stored in the state parameter after the authentication is successful.However, I redirected the user to the home page (/) because the application does not have protected pages. The location state is supposed to be obtained from the URL but I hard-coded it with a slash (/) and assigned it to the
from
variable. When I get time I will write a statement to retrieve the location state from the URL instead of using a hard-coded slash (/).3. The access and refresh tokens returned by the GitHub API are to be used with only GitHub. The access token is required to retrieve the GitHub user’s information. I understand the point you are trying to make but since our API is different from GitHub API, we also need to generate our own access and refresh tokens.
Leave a ReplyCancel reply
This site uses Akismet to reduce spam.Learn how your comment data is processed.
Support Me!

Recent posts
Categories
- C#(2)
- C++(1)
- CSS / SCSS(3)
- Deno(8)
- Golang(31)
- JavaScript(5)
- NextJs(38)
- NodeJS(32)
- Programming(19)
- Python(19)
- React(38)
- Rust(35)
- Svelte(5)
- Vue(7)