Authentication is always a delicate subject since it is one of the core layers guarding your application's features against unwanted access.
There are many ways to handle authentication and one of them is to rely on authentication providers, trusted entities that can authenticate someone for you. You are probably already familiar with this way of managing authentication as many applications suggest to "Sign in with Microsoft" or "Log in with Google".
In this article, we will discuss how to configure PocketBase to use GitHub as an authentication provider for your Angular app, here's an overview of what we will be building:
π If you would like to follow along, you can clone the code of this article using this repository and follow along using the branches, starting with
01-initial-setup
.
What is PocketBase
PocketBase is a Backend as a Service (BaaS) like FireBase, SupaBase, Appwrite and many others.
What differentiates it from others however, is that it consists of a single executable file making it really easy to run locally or to self-host, where other solutions often require either connecting to a cloud instance, or setting up several Docker containers.
PocketBase aims to be used as a backend solution, providing authentication, en embedded database, realtime subscriptions and built-in authentication management.
It can also do much more than that, and you can have a look at their documentation or online demo to try for yourself.
There is also a pretty good video of Fireship on the subject:
Integrating GitHub OAuth with PocketBase
Before actually consuming it, we should first setup our backend in our Angular project.
π² Start here with the branch:
01-initial-setup
, the final result will be in02-pocketbase-installation
.
Setting Up PocketBase
Since PocketBase is a single executable, we can download it either from the direct link in the docs or on the GitHub releases page.
π As of the time I'm writting this article, the current version of PocketBase is 0.22.19
Once downloaded, open the archive and copy pocketbase.exe
into the Angular project. I placed mine at pocketbase/pocketbase.exe
:
Once in your project, simply run it with the command pocketbase serve
, you should observe the following output:
Some files are also automatically created by PocketBase on startup, consisting of its initial configuration.
You can now navigate to http://127.0.0.1:8090/_/
where you will be asked for the credentials of the administrator account of your PocketBase instance. This user will be allowed to update the internals of your backend, create new tables, routes, and much more:
Upon creation you should be redirected to the administration dashboard:
We're all set!
Registering GitHub as an OAuth Provider
To configure GitHub as an OAuth provider, we should first get credentials from the platform by registering our applications in GitHub.
In order to create a new OAuth application, navigate to https://github.com/settings/apps
and click on OAuth Apps
. You can then click on the top right button labeled New OAuth App
.
You will be asked for some informations that you can fill as you see fit, except for the Authorization callback URL
which is handled by PocketBase and should redirect to /api/oauth2-redirect
of your instance. In our case, the desired URL is http://localhost:8090/api/oauth2-redirect
:
When created, copy the Client ID
and generate a new Client secrets
to copy its value as well.
Back to the PocketBase administration panel, in the sidebar, click on the wrench icon to navigate to http://127.0.0.1:8090/_/#/settings
. From there, click on the Auth providers
item in the Authentication
section. Amongst the listed providers, you should see GitHub:
If you click on the cog, a menu opens and you can specify the values with the OAuth application we just created:
Once filled, you can click on Save changes
and noticed that GitHub now appears as enabled:
And just like that, we configured our PocketBase backend to use GitHub as an OAuth provider!
Consuming PocketBase from our Angular Application
Now that we have a running backend with OAuth2 configured, we can interract with it like we would with any other backend.
π² Start here with the branch
02-pocketbase-installation
, the final result will be in03-consuming-pocketbase
.
Initializing the Client
The easiest way to get started with PocketBase in a JS project is to use their JS Client-side SDK available on GitHub.
Let's get started by installing the required dependency:
pnpm install pocketbase
Once done, we can instantiate a new client using the URL PocketBase is running at:
import PocketBase from 'pocketbase';
const pb = new PocketBase('http://127.0.0.1:8090');
However, we can also take advantage of Angular's powerful dependency injection system and instead wrap it into an injection token:
// π src/app/pocketbase.provider.ts
export const PocketBaseClient = new InjectionToken<PocketBase>(
'PocketBase client',
);
We can then expose a method that will manage the PocketBase client's creation for us:
// π src/app/pocketbase.provider.ts
export const providePocketBase = (baseUrl: string): EnvironmentProviders =>
makeEnvironmentProviders([
{
provide: PocketBaseClient,
// π You could also inject `environment` here instead
useFactory: () => new PocketBase(baseUrl),
},
]);
We now have to register our provider in main.ts
:
// π src/main.ts
bootstrapApplication(AppComponent, {
providers: [
provideExperimentalZonelessChangeDetection(),
+ providePocketBase('http://localhost:8090'),
],
}).catch((err) => console.error(err));
And we can now inject the client into the AuthenticationService
:
// π src/app/authentication.service.ts
@Injectable({ providedIn: 'root' })
export class AuthenticationService {
+ readonly #pocketBase = inject(PocketBaseClient);
// ...
}
Implementing Authentication with PocketBase
Since PocketBase is managing authentication, we don't have to be orchestrating the sign in process, instead we only need to declare what logic we would like to run if the authentication status changes.
In PocketBase, the authStore
is in charge of managing authentication and its events.
In our case, we would like to update the user's name whenever he signs in by registering a callback:
// π src/app/authentication.service.ts
@Injectable({ providedIn: 'root' })
export class AuthenticationService {
// ...
+ constructor() {
+ this.#pocketBase.authStore.onChange((_token, user) => {
+ this.#userName.set(user?.['username'] ?? null);
+ });
+ }
// ...
}
Signing Methods
We now have configured pretty much everything, except the actual sign in and sign out methods.
Signing out is the most straightforward method to write since it just consists of clearing PocketBase's authStore
:
// π src/app/authentication.service.ts
@Injectable({ providedIn: 'root' })
export class AuthenticationService {
// ...
signOut(): void {
- this.#userName.set(null);
+ this.#pocketBase.authStore.clear();
}
}
Signing in also doesn't require much to write, since PocketBase and its SDK will be handling all the complexity. All we need to do is to trigger the authentication challenge for the users
collection, using github
as a provider.
Since this is a Promise
, we can also log an eventual error that might occurred:
// π src/app/authentication.service.ts
@Injectable({ providedIn: 'root' })
export class AuthenticationService {
// ...
signInWithGithub(): void {
- this.#userName.set('pBouillon');
+ this.#pocketBase
+ .collection('users')
+ .authWithOAuth2({ provider: 'github' })
+ .catch((error) => console.log(error.originalError));
}
}
If you now run the demo again, you should be able to sign in using GitHub:
Congrats! You've just achieved authentication in your Angular app using GitHub as an OAuth provider π
π You can still go further by implementing a mechanism to detect if the user is already signed in when the page opens using by storing a cookie with its details and read it on initialization. You can look into the
authServer#exportToCookie
method as a starting point.
Wrapping up
With the last piece of codes added and the demo fully functional, we successfully have setup a backend using PocketBase, and configured GitHub to act as our authentication provider.
Should you add any other provider (Microsoft, Google, Facebook or even Discord) the process is globally the same, except for some specificities some might require.
However PocketBase is much more than that and I highly encourage you to check out all the features it has. Amongst many other things, you can manage your data, create table view, see logs history, create custom API routes, create data migrations, etc.
In my experience, PocketBase make it really easy to work on side project where you quickly want to get started without having to deal with the complexity of writing your own backend from scratch.
Moreover, with the options to self-host it, or the free alternatives such as PocketHost, going to production is really simple.
You can still check-out the docs to learn more about it, or browse this article's repository:
pBouillon / DEV.GitHubAuthWithPocketBase
Demo code for the "Using GitHub as an Authentication Provider in Your Angular App with PocketBase" article on DEV
Using GitHub as an Authentication Provider in Your Angular App with PocketBase
Demo code for the "Using GitHub as an Authentication Provider in Your Angular App with PocketBase" article on DEV
I hope your learned something useful!
Photo by Nicole Geri on Unsplash
Top comments (1)
This was super helpful! Quick question thoughβare there any specific security considerations we should keep in mind when using PocketBase with GitHub OAuth?