├── .env ├── .gitignore ├── LICENSE ├── README.md ├── config └── config.go ├── controllers ├── github.go └── google.go ├── go.mod ├── go.sum └── main.go /.env: -------------------------------------------------------------------------------- 1 | GOOGLE_CLIENT_ID = 2 | GOOGLE_CLIENT_SECRET = 3 | GITHUB_CLIENT_ID = 4 | GITHUB_CLIENT_SECRET = 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.env 4 | *.exe~ 5 | *.env 6 | *.dll 7 | *.so 8 | *.dylib 9 | 10 | # Test binary, built with `go test -c` 11 | *.test 12 | 13 | # Output of the go coverage tool, specifically when used with LiteIDE 14 | *.out 15 | 16 | # Dependency directories (remove the comment below to include it) 17 | # vendor/ 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Siddhesh Khandagale 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # go-oauth2 -------------------------------------------------------------------------------- /config/config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "log" 5 | "os" 6 | 7 | "github.com/joho/godotenv" 8 | "golang.org/x/oauth2" 9 | "golang.org/x/oauth2/github" 10 | "golang.org/x/oauth2/google" 11 | ) 12 | 13 | type Config struct { 14 | GoogleLoginConfig oauth2.Config 15 | GitHubLoginConfig oauth2.Config 16 | } 17 | 18 | var AppConfig Config 19 | 20 | func GoogleConfig() oauth2.Config { 21 | err := godotenv.Load(".env") 22 | if err != nil { 23 | log.Fatalf("Some error occured. Err: %s", err) 24 | } 25 | 26 | AppConfig.GoogleLoginConfig = oauth2.Config{ 27 | RedirectURL: "http://localhost:8080/google_callback", 28 | ClientID: os.Getenv("GOOGLE_CLIENT_ID"), 29 | ClientSecret: os.Getenv("GOOGLE_CLIENT_SECRET"), 30 | Scopes: []string{"https://www.googleapis.com/auth/userinfo.email", 31 | "https://www.googleapis.com/auth/userinfo.profile"}, 32 | Endpoint: google.Endpoint, 33 | } 34 | 35 | return AppConfig.GoogleLoginConfig 36 | } 37 | 38 | func GithubConfig() oauth2.Config { 39 | err := godotenv.Load(".env") 40 | if err != nil { 41 | log.Fatalf("Some error occured. Err: %s", err) 42 | } 43 | 44 | AppConfig.GitHubLoginConfig = oauth2.Config{ 45 | RedirectURL: "http://localhost:8080/github_callback", 46 | ClientID: os.Getenv("GITHUB_CLIENT_ID"), 47 | //RedirectURL: fmt.Sprintf( 48 | // "https://github.com/login/oauth/authorize?scope=user:repo&client_id=%s&redirect_uri=%s", os.Getenv("GITHUB_CLIENT_ID"), "http://localhost:8080/github_callback"), 49 | ClientSecret: os.Getenv("GITHUB_CLIENT_SECRET"), 50 | Scopes: []string{"user", "repo"}, 51 | Endpoint: github.Endpoint, 52 | } 53 | 54 | return AppConfig.GitHubLoginConfig 55 | } 56 | -------------------------------------------------------------------------------- /controllers/github.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "io/ioutil" 7 | "net/http" 8 | 9 | "github.com/Siddheshk02/go-oauth2/config" 10 | "github.com/gofiber/fiber/v2" 11 | ) 12 | 13 | func GithubLogin(c *fiber.Ctx) error { 14 | 15 | url := config.AppConfig.GitHubLoginConfig.AuthCodeURL("randomstate") 16 | 17 | c.Status(fiber.StatusSeeOther) 18 | c.Redirect(url) 19 | return c.JSON(url) 20 | } 21 | 22 | func GithubCallback(c *fiber.Ctx) error { 23 | 24 | state := c.Query("state") 25 | if state != "randomstate" { 26 | return c.SendString("States don't Match!!") 27 | } 28 | 29 | code := c.Query("code") 30 | 31 | githubcon := config.GithubConfig() 32 | fmt.Println(code) 33 | 34 | token, err := githubcon.Exchange(context.Background(), code) 35 | if err != nil { 36 | return c.SendString("Code-Token Exchange Failed") 37 | } 38 | fmt.Println(token) 39 | 40 | resp, err := http.Get("https://api.github.com/user/repo?access_token=" + token.AccessToken) 41 | //resp, err := http.Get('Authorization: token my_access_token' https://api.github.com/user/repos) 42 | if err != nil { 43 | return c.SendString("User Data Fetch Failed") 44 | } 45 | fmt.Println(resp) 46 | 47 | userData, err := ioutil.ReadAll(resp.Body) 48 | if err != nil { 49 | return c.SendString("JSON Parsing Failed") 50 | } 51 | fmt.Println(userData) 52 | 53 | return c.SendString(string(userData)) 54 | 55 | } 56 | -------------------------------------------------------------------------------- /controllers/google.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | "context" 5 | "io/ioutil" 6 | "net/http" 7 | 8 | "github.com/Siddheshk02/go-oauth2/config" 9 | "github.com/gofiber/fiber/v2" 10 | ) 11 | 12 | func GoogleLogin(c *fiber.Ctx) error { 13 | 14 | url := config.AppConfig.GoogleLoginConfig.AuthCodeURL("randomstate") 15 | 16 | c.Status(fiber.StatusSeeOther) 17 | c.Redirect(url) 18 | return c.JSON(url) 19 | } 20 | 21 | func GoogleCallback(c *fiber.Ctx) error { 22 | state := c.Query("state") 23 | if state != "randomstate" { 24 | return c.SendString("States don't Match!!") 25 | } 26 | 27 | code := c.Query("code") 28 | 29 | googlecon := config.GoogleConfig() 30 | 31 | token, err := googlecon.Exchange(context.Background(), code) 32 | if err != nil { 33 | return c.SendString("Code-Token Exchange Failed") 34 | } 35 | 36 | resp, err := http.Get("https://www.googleapis.com/oauth2/v2/userinfo?access_token=" + token.AccessToken) 37 | if err != nil { 38 | return c.SendString("User Data Fetch Failed") 39 | } 40 | 41 | userData, err := ioutil.ReadAll(resp.Body) 42 | if err != nil { 43 | return c.SendString("JSON Parsing Failed") 44 | } 45 | 46 | return c.SendString(string(userData)) 47 | 48 | } 49 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/Siddheshk02/go-oauth2 2 | 3 | go 1.19 4 | 5 | require ( 6 | github.com/gofiber/fiber/v2 v2.41.0 7 | golang.org/x/oauth2 v0.4.0 8 | ) 9 | 10 | require ( 11 | cloud.google.com/go/compute/metadata v0.2.0 // indirect 12 | github.com/andybalholm/brotli v1.0.4 // indirect 13 | github.com/golang/protobuf v1.5.2 // indirect 14 | github.com/joho/godotenv v1.4.0 15 | github.com/klauspost/compress v1.15.14 // indirect 16 | github.com/mattn/go-colorable v0.1.13 // indirect 17 | github.com/mattn/go-isatty v0.0.17 // indirect 18 | github.com/mattn/go-runewidth v0.0.14 // indirect 19 | github.com/rivo/uniseg v0.4.3 // indirect 20 | github.com/valyala/bytebufferpool v1.0.0 // indirect 21 | github.com/valyala/fasthttp v1.43.0 // indirect 22 | github.com/valyala/tcplisten v1.0.0 // indirect 23 | golang.org/x/net v0.5.0 // indirect 24 | golang.org/x/sys v0.4.0 // indirect 25 | google.golang.org/appengine v1.6.7 // indirect 26 | google.golang.org/protobuf v1.28.0 // indirect 27 | ) 28 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go/compute/metadata v0.2.0 h1:nBbNSZyDpkNlo3DepaaLKVuO7ClyifSAmNloSCZrHnQ= 2 | cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= 3 | github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= 4 | github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= 5 | github.com/gofiber/fiber/v2 v2.41.0 h1:YhNoUS/OTjEz+/WLYuQ01xI7RXgKEFnGBKMagAu5f0M= 6 | github.com/gofiber/fiber/v2 v2.41.0/go.mod h1:RdebcCuCRFp4W6hr3968/XxwJVg0K+jr9/Ae0PFzZ0Q= 7 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 8 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 9 | github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= 10 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 11 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 12 | github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= 13 | github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= 14 | github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= 15 | github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= 16 | github.com/klauspost/compress v1.15.14 h1:i7WCKDToww0wA+9qrUZ1xOjp218vfFo3nTU6UHp+gOc= 17 | github.com/klauspost/compress v1.15.14/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= 18 | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 19 | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 20 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 21 | github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= 22 | github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 23 | github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= 24 | github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= 25 | github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= 26 | github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= 27 | github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= 28 | github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= 29 | github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= 30 | github.com/valyala/fasthttp v1.43.0 h1:Gy4sb32C98fbzVWZlTM1oTMdLWGyvxR03VhM6cBIU4g= 31 | github.com/valyala/fasthttp v1.43.0/go.mod h1:f6VbjjoI3z1NDOZOv17o6RvtRSWxC77seBFc2uWtgiY= 32 | github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= 33 | github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= 34 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 35 | golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 36 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 37 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 38 | golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= 39 | golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= 40 | golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= 41 | golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M= 42 | golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= 43 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 44 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 45 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 46 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 47 | golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 48 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 49 | golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= 50 | golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 51 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 52 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 53 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 54 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 55 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 56 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 57 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 58 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 59 | google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= 60 | google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 61 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 62 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 63 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 64 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 65 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/Siddheshk02/go-oauth2/config" 5 | "github.com/Siddheshk02/go-oauth2/controllers" 6 | "github.com/gofiber/fiber/v2" 7 | ) 8 | 9 | func main() { 10 | app := fiber.New() 11 | 12 | config.GoogleConfig() 13 | config.GithubConfig() 14 | 15 | app.Get("/google_login", controllers.GoogleLogin) 16 | app.Get("/google_callback", controllers.GoogleCallback) 17 | app.Get("/github_login", controllers.GithubLogin) 18 | app.Get("/github_callback", controllers.GithubCallback) 19 | 20 | app.Listen(":8080") 21 | 22 | } 23 | --------------------------------------------------------------------------------