OAuth
Fully working OAuth flow without any external provider + Magic Links
Configuration
The base application includes configurations for two providers: Google and GitHub, plus a Magic Link option.
- To enable the Google provider, you need to set the
GOOGLE_CLIENT_ID
andGOOGLE_CLIENT_SECRET
environment variables. - To enable the GitHub provider, you need to set the
GITHUB_CLIENT_ID
andGITHUB_CLIENT_SECRET
environment variables.
services:
server:
environment:
GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID}
GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET}
GITHUB_CLIENT_ID: ${GITHUB_CLIENT_ID}
GITHUB_CLIENT_SECRET: ${GITHUB_CLIENT_SECRET}
The Magic Link option requires only a working email provider. If the log
option is chosen for email configuration, the magic link will appear in the application logs.
Implementation Details
The OAuth implementation does not depend on any external providers. It’s built using the golang.org/x/oauth2
library. The main logic can be found in the /auth/provider.go
file.
Adding a new provider
To add a new provider, follow these steps in the /auth/provider.go
file:
Backend
- Add the new provider to the
Provider
constant.
const (
Google Provider = "google"
GitHub Provider = "github"
Email Provider = "email"
Discord Provider = "discord"
)
- Create a new provider struct.
type oauthDiscord struct {
config oauth2.Config
}
- Return the new provider in the
NewProvider
function:
case Discord:
return &oauthDiscord{
config: oauth2.Config{
ClientID: system.DISCORD_CLIENT_ID,
ClientSecret: system.DISCORD_CLIENT_SECRET,
Endpoint: oauth2.Endpoint{
AuthURL: "https://discord.com/api/oauth2/authorize",
TokenURL: "https://discord.com/api/oauth2/token",
},
RedirectURL: system.CLIENT_URL + "/auth/discord",
Scopes: []string{"identify", "email"},
},
}
- Implement the required methods:
func (o *oauthDiscord) getProvider() Provider {
return Discord
}
func (o *oauthDiscord) getOAuthConfig() *oauth2.Config {
return &o.config
}
func (o *oauthDiscord) getUserInfo(accessToken string) (*UserInfo, error) {
// Implement the logic to get the user info
}
-
Add any new secrets in the
env.go
file. -
Fill in the
docker-compose.yml
file with the new provider configuration.
services:
server:
environment:
DISCORD_CLIENT_ID: ${DISCORD_CLIENT_ID}
DISCORD_CLIENT_SECRET: ${DISCORD_CLIENT_SECRET}
Frontend
On the frontend side, all you need to do is create a new form with a button and a hidden input that holds the new provider name.
SvelteKit:
<form action="?/login" method="post" on:submit|preventDefault={handleSubmit}>
<input type="hidden" name="provider" value="discord" />
<Button class="w-full">
<svelte:fragment slot="icon">
<DiscordIcon class="h-5 w-5" />
</svelte:fragment>
Continue with Discord
</Button>
</form>
NextJS:
<form action={submit}>
<input type="hidden" name="provider" value="discord" />
<Button className="w-full" icon={<DiscordIcon className="h-5 w-5" />}>
Continue with Discord
</Button>
</form>
Getting Secrets
Github
To get the GITHUB_CLIENT_ID
and GITHUB_CLIENT_SECRET
, you need to create a new GitHub App:
- Go to GitHub Developer Settings.
- Click on “New GitHub App”.
- Fill in the
GitHub App name
,Homepage URL
,Callback URL
. - Check
Request user authorization (OAuth) during installation
. - Uncheck
Active
onWebhook
. - Check
Any account
onWhere can this GitHub App be installed?
. - Click on “Create GitHub App”.
- Click on “Generate a new client secret”.
- Copy the
Client ID
andClient Secret
.
To get the GOOGLE_CLIENT_ID
and GOOGLE_CLIENT_SECRET
, you need to create a new Google Project:
- Go to Google Cloud Console.
- Click on “Select a project” and then “New Project”.
- Fill in the
Project name
and click on “Create”. - Go to “APIs & Services” > “OAuth consent screen”.
- Fill all the required fields and click on “Save and continue”.
- Go to “APIs & Services” > “Credentials”.
- Click on “Create credentials” > “OAuth client ID”.
- Select “Web application”.
- Fill in the
Name
,Authorized redirect URIs
and click on “Create”. - Copy the
Client ID
andClient Secret
.
Need help?
Visit our discord server to ask any questions, make suggestions and give feedback :).