Movatterモバイル変換


[0]ホーム

URL:


CodevoWeb

PressESC to close

Google OAuth Authentication With Vue.js and Golang

0Comments23

This article will teach you how to add Google OAuth Authentication to yourVue.js, MongoDB-Go-Driver, and Golang applications.

Also, after the user is authenticated on the server, we will return JWT access and refresh token cookies to their browser or client.

Related Articles:

Google OAuth Authentication With Vue.js, MongoDB and Golang

Prerequisites

  • Some knowledge of HTML, CSS,Vue.js, and Golang is needed
  • Have Golang installed on your machine

Create the Google client ID and secret

Search forGoogle OAuth in your preferred browser and click on the first link in the search results. You will then be taken toOAuth 2.0 to Access Google APIs.

TheOAuth 2.0 to Access Google APIs page contains some instructions on how to obtain the access keys. However, I will guide you step-by-step on how to retrieve the access keys.

On theOAuth 2.0 to Access Google APIs page, click on theGoogle API Console link to open the Google API console where we will generate the OAuth 2.0 client credentials.

Note: A Google account is required to access theGoogle API Console page.

Create a New Console Project

Now click on theGoogle-Oauth dropdown, and a modal should appear where you can either choose an existing project or create a new one.

If you haven’t created any Google API project yet then click on the“New Project” button and type the name of the project. Next, click on the“CREATE” button.

google oauth new project

Now grab some coffee and wait a few seconds for Google to set up the project. After the project has been created, a success notification will appear in the top-right corner.

Next, click on the“SELECT PROJECT” button on the notification and tap anywhere on the browser to close the modal.

google oauth new project success notification

Set up the OAuth Consent Screen

To start, we need to create the consent screen before we can generate the client ID and secret. The consent screen is where the user will be taken to when they click on the“Sign In with Google” button.

Now select theOAuth consent screen menu under the“APIs & Services” on the sidebar. On theOAuth consent screen, choose the ExternalUser Type if it’s a public-facing application you are building and click on the“CREATE” button.

google oauth consent screen setup

Next, provide the appropriate information needed for the consent screen.

google oauth consent screen registration

Next, click on the“SAVE AND CONTINUE” button.

google oauth consent screen registration 2

On the scopes screen, click on the“ADD OR REMOVE SCOPES” button. Feel free to play around with the available scopes to better understand their use case. However, am only interested in the user’s email and profile information.

Scroll down and click on the“UPDATE” button after selecting the scopes. Next, click on the“SAVE AND CONTINUE” button.

google oauth consent screen select scopes

Now click on theADD USERS button on theTest users screen to add the Google account that will be allowed to sign in to your application whilst in sandbox mode.

Next, click on the“SAVE AND CONTINUE” button after adding the Google account test user.

Now on theSummary screen go through the information you provided and click on the“BACK TO DASHBOARD” button.

Generate the OAuth Client ID and Secret

Under“APIs & Services”, select theCredentials menu and click on“CREATE CREDENTIALS” on theCredentials screen. Next, click onOAuth client ID.

google oauth create credentials

Now provide the required information needed for the OAuth app. The authorized redirect URL should point to a route on your Golang server. Doing it this way will enable us to make theGET request to authorize the user directly from the consent screen.

google oauth credentials

Next, click on the“CREATE” button to generate the client ID and secret.

Edit the.env file in the server directory and add the generated client ID, secret, and redirect URL.

.env

GOOGLE_OAUTH_CLIENT_ID=your client Id hereGOOGLE_OAUTH_CLIENT_SECRET=your client secret hereGOOGLE_OAUTH_REDIRECT_URL=http://localhost:8000/api/sessions/oauth/google

In addition, add the credentials to the.env.local file in the Vue.js application.

VITE_SERVER_ENDPOINT=http://localhost:8000VITE_GOOGLE_OAUTH_CLIENT_ID=VITE_GOOGLE_OAUTH_CLIENT_SECRET=VITE_GOOGLE_OAUTH_REDIRECT=http://localhost:8000/api/sessions/oauth/google

UseVue_App_ prefix if you generated the app with the@vue/cli .

Generate the Consent Screen URL in Vue.js

Now that we have all the configurations in place, we are now ready to add the Google OAuth logic to the Vue.js application.

Next, we need to create a function to generate the OAuth consent screen URL with the client ID, the scopes, and the redirect URL.

src/utils/getGoogleUrl.ts

export const getGoogleUrl = (from) => {  const rootUrl = `https://accounts.google.com/o/oauth2/v2/auth`;  const options = {    redirect_uri: import.meta.env.VITE_GOOGLE_OAUTH_REDIRECT,    client_id: import.meta.env.VITE_GOOGLE_OAUTH_CLIENT_ID,    access_type: 'offline',    response_type: 'code',    prompt: 'consent',    scope: [      'https://www.googleapis.com/auth/userinfo.profile',      'https://www.googleapis.com/auth/userinfo.email',    ].join(' '),    state: from,  };  const qs = new URLSearchParams(options);  return `${rootUrl}?${qs.toString()}`;};

Build the Google OAuth Button with Vue.js

Next, let’s create a simple login screen with a Google OAuth button havinghref={getGoogleUrl(from)}.

vuejs google oauth authentication

src/App.vue

<script setup>import GoogleLogo from './assets/google.svg';import { getGoogleUrl } from './utils/getGoogleUrl';const from = '/';</script><template>  <div class="container">    <div class="social-auth">      <a :href="getGoogleUrl(from)" class="google-auth">        <img :src="GoogleLogo" alt="Google 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;}.google-auth {  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;}.google-auth img {  height: 4rem;  margin-right: 1rem;}.google-auth span {  font-size: 1.8rem;}.google-auth:hover {  box-shadow: 0 1px 13px 0 rgb(0 0 0 / 15%);}</style>

On the login screen, click on the Google OAuth button and you should be redirected to the consent screen where you will be asked to select an account from the available logged-in Google accounts.

On the consent screen, click on the test Google account or sign in with the test account if you haven’t already done that.

vuejs google oauth authentication consent screen

The Golang server should return a404 error assuming it is running.

Now take a careful look at the authorized redirect URI and you should see a unique code in the query string.

Later, we’ll use that code to request an access token before making another request with the access token to retrieve the user’s profile information.

The404 error was returned by the Golang server because we haven’t implemented the Google OAuth logic yet.

google OAuth 2 click on google account

Implement the Google OAuth in Golang and MongoDB

Edit theconfig/default.go file and add the Google OAuth client ID, the Vue.js origin URL, the client secret, and the authorized callback URL.

You need to add the environment variables to the Config struct forViper to load and make them available throughout 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"`}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 Google OAuth Access Token and User’s Profile Data

Now create autils/googleOAuth.go file in the root directory and add these two functions:

  • GetGoogleOauthToken() – Retrieves the OAuth Access Token from the Google API.
  • GetGoogleUser() – Exchanges the access token for the user’s profile data.

utils/googleOAuth.go

type GoogleOauthToken struct {Access_token stringId_token     string}type GoogleUserResult struct {Id             stringEmail          stringVerified_email boolName           stringGiven_name     stringFamily_name    stringPicture        stringLocale         string}func GetGoogleOauthToken(code string) (*GoogleOauthToken, error) {const rootURl = "https://oauth2.googleapis.com/token"config, _ := config.LoadConfig(".")values := url.Values{}values.Add("grant_type", "authorization_code")values.Add("code", code)values.Add("client_id", config.GoogleClientID)values.Add("client_secret", config.GoogleClientSecret)values.Add("redirect_uri", config.GoogleOAuthRedirectUrl)query := values.Encode()req, err := http.NewRequest("POST", rootURl, bytes.NewBufferString(query))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}var GoogleOauthTokenRes map[string]interface{}if err := json.Unmarshal(resBody, &GoogleOauthTokenRes); err != nil {return nil, err}tokenBody := &GoogleOauthToken{Access_token: GoogleOauthTokenRes["access_token"].(string),Id_token:     GoogleOauthTokenRes["id_token"].(string),}return tokenBody, nil}func GetGoogleUser(access_token string, id_token string) (*GoogleUserResult, error) {rootUrl := fmt.Sprintf("https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=%s", access_token)req, err := http.NewRequest("GET", rootUrl, nil)if err != nil {return nil, err}req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", id_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 GoogleUserRes map[string]interface{}if err := json.Unmarshal(resBody, &GoogleUserRes); err != nil {return nil, err}userBody := &GoogleUserResult{Id:             GoogleUserRes["id"].(string),Email:          GoogleUserRes["email"].(string),Verified_email: GoogleUserRes["verified_email"].(bool),Name:           GoogleUserRes["name"].(string),Given_name:     GoogleUserRes["given_name"].(string),Picture:        GoogleUserRes["picture"].(string),Locale:         GoogleUserRes["locale"].(string),}return userBody, nil}

Edit the User Model

If you came from a previous article in this series then update themodels/user.model.go file to have thePhoto andProvider fields.

Now, when a user registers an account using Google OAuth, we’ll set theprovider field toGoogle . However, a normal user who creates the account using email and password will have theprovider to belocal .

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,}}

Include a Service to Upsert the User

Let’s define a utility 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 let’s add anUpsertUser method to theUserService interface. TheUpsertUser function will be responsible for accessing and mutating 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 code below to theservices/user.service.impl.go file. TheUpsertUser method will enable us 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}

In the above code snippets, you’ll notice that we used.SetUpsert(true) on theFindOneAndUpdateOptions instance returned by evokingoptions.FindOneAndUpdate() .

Adding.SetUpsert(true) will inform MongoDB to create a new user document if the email used in the BSON query does not exist in the database. However, MongoDB will only update the user document if that email already exists.

Define the Google OAuth Controller

Now let’s install theGolang JWT package to enable us to generate the JSON Web Tokens.

At the time of writing this article, the current version isv4 but this might change in the future so visit theirGitHub page to download the recent version.

go get -u github.com/golang-jwt/jwt/v4

Next, create these two functions to sign 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}

Now let’s include theGoogleOAuth handler in thecontrollers/auth.controller.go file. This handler will be evoked when Google redirects the user 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 Tokenfunc (ac *AuthController) RefreshAccessToken(ctx *gin.Context) {message := "could not refresh access token"cookie, err := ctx.Cookie("refresh_token")if err != nil {ctx.AbortWithStatusJSON(http.StatusForbidden, gin.H{"status": "fail", "message": message})return}config, _ := config.LoadConfig(".")sub, err := utils.ValidateToken(cookie, config.RefreshTokenPublicKey)if err != nil {ctx.AbortWithStatusJSON(http.StatusForbidden, gin.H{"status": "fail", "message": err.Error()})return}user, err := ac.userService.FindUserById(fmt.Sprint(sub))if err != nil {ctx.AbortWithStatusJSON(http.StatusForbidden, gin.H{"status": "fail", "message": "the user belonging to this token no logger exists"})return}access_token, err := utils.CreateToken(config.AccessTokenExpiresIn, user.ID, config.AccessTokenPrivateKey)if err != nil {ctx.AbortWithStatusJSON(http.StatusForbidden, gin.H{"status": "fail", "message": err.Error()})return}ctx.SetCookie("access_token", access_token, config.AccessTokenMaxAge*60, "/", "localhost", false, true)ctx.SetCookie("logged_in", "true", config.AccessTokenMaxAge*60, "/", "localhost", false, false)ctx.JSON(http.StatusOK, gin.H{"status": "success", "access_token": access_token})}func (ac *AuthController) GoogleOAuth(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.GetGoogleOauthToken(code)if err != nil {ctx.JSON(http.StatusBadGateway, gin.H{"status": "fail", "message": err.Error()})}user, err := utils.GetGoogleUser(tokenRes.Access_token, tokenRes.Id_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.Picture,Provider:  "google",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 Route

Next, create aroutes/session.routes.go file and add the code snippets below.

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)}

We created a new route file because we will later implement GitHub and Facebook OAuth and it makes sense to group them in a single route file.

Register the Session Router

Next, let’s add the router we created above to theGin Gonic middleware stack in themain.go file. Also, we need to install thecors package 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 add Google OAuth Authentication to your Vue.js, Golang,Gin Gonic, and MongoDB applications.

Check out the source code here:

Share Article:

Google OAuth Authentication React.js and Golang

Left Arrow

GitHub OAuth Authentication Vuejs and Golang

Right Arrow

Leave a ReplyCancel reply

This site is protected by reCAPTCHA and the GooglePrivacy Policy andTerms of Service apply.

This site uses Akismet to reduce spam.Learn how your comment data is processed.

Support Me!

paypal donate button

Recent posts

Categories


[8]ページ先頭

©2009-2025 Movatter.jp