DEV Community

Cover image for Qwik Authentication with Auth.js
Ayoub Alouane for This is Learning

Posted on

Qwik Authentication with Auth.js

Introduction to Auth.js

Auth.js is a well-known library for authentication that is used by JS Frameworks; with Auth.js we have less complexity. We also had a set of auth providers like GitHub, Google, Facebook, and others, and it can be integrated into multiple frameworks like NextJS, SveltKit, SolidStart, and Qwik.

Auth.js comes with multiple features, that enable simplicity, productivity, flexibility and multiple providers. Here is the main features of Auth.js:

  • Providers: Auth.js has the support of multiple providers that simplify for us the authentication process in our applications (Github, Google, Facebook, Twitter …). It also offers SSO services and also a simple traditional authentification.
  • Management: Auth.js is doing a lot to help us focus on our business logic, so it manages Tokens, stores them, and takes care of refreshing them automatically.
  • Configuration: Auth.js is simple to configure, with an easy installation, error handling, custom forms for login and registration, and simple integrations with providers.
  • Integrations: Auth.js integrates with JS frameworks easily thanks to its documentation that provide a simple guide to follow.
  • Security: Auth.js provides a high level of protection, it's a developer-friendly library, but we should not forget that it has a complexity under the hood that offers us a great level of security for our data.

Brief Introduction to Qwik

Qwik is a framework created by the creator of Angular, Miško Hevery, with a collaboration of Adam Bradley, who created Ionic, and Manu Almeida, who created Gin Framework.

Qwik, the HTML first framework’s philosophy is clear: make the fastest possible time-to-interactive (to do it faster by doing nothing).

The framework delays the invocation of the javascript as much as possible and invokes it only what is absolutely needed. The focus is on the first load.

If you want to dive deep in Qwik, we already have an article about it:

Integrate Auth.js to Qwik

Prerequisites

To get started with Qwik locally, we need the following:

App Creation

Using the Qwik CLI we will start by starting a new Qwik Project:

npm create qwik@latest

Enter fullscreen mode Exit fullscreen mode

Steps to create the project:

┌  Let's create a  Qwik App  ✨ (v1.0.0)
│
◇  Where would you like to create your new project?
│  ./qwik-auth
│
●  Creating new project in  /Users/mac/Documents/articles/qwik-auth  ... 🐇
│
◇  Select a starter
│  Basic App (QwikCity)
│
◇  Would you like to install npm dependencies?
│  Yes
│
◇  Initialize a new git repository?
│  Yes
│
◇  Created App 🐰
│
◇  Git initialized 🎲
│
◇  Installed dependencies 📋
│
○  Result ────────────────────────────────────────────────╮
│                                                         │
│  🦄  Success!  Project created in qwik-auth directory   │
│                                                         │
│  🐰 Next steps:                                         │
│     cd qwik-auth                                        │
│     npm start                                           │
│                                                         │
│  🤍 Integrations? Add Netlify, Cloudflare, Tailwind...  │
│     npm run qwik add                                    │
│                                                         │
│  📄 Relevant docs:                                      │
│     https://qwik.builder.io/docs/getting-started/       │
│                                                         │
│  💬 Questions? Start the conversation at:               │
│     https://qwik.builder.io/chat                        │
│     https://twitter.com/QwikDev                         │
│                                                         │
│  👀 Presentations, Podcasts and Videos:                 │
│     https://qwik.builder.io/media/                      │
│                                                         │
│                                                         │
├─────────────────────────────────────────────────────────╯
│
└  Happy coding! 🐇
Enter fullscreen mode Exit fullscreen mode

To run the server, we will need the following command:

npm start
Enter fullscreen mode Exit fullscreen mode

On port 5173 we will have our application running. Now we will install Auth.js:

npm run qwik add auth
Enter fullscreen mode Exit fullscreen mode

After installing Auth.js we should go to the file vite.config.js in order to add some configuration "optimizeDeps":

import { defineConfig } from 'vite';
import { qwikVite } from '@builder.io/qwik/optimizer';
import { qwikCity } from '@builder.io/qwik-city/vite';
import tsconfigPaths from 'vite-tsconfig-paths';

export default defineConfig(() => {
  return {
    plugins: [qwikCity(), qwikVite(), tsconfigPaths()],
    preview: {
      headers: {
        'Cache-Control': 'public, max-age=600',
      },
    },
    **optimizeDeps: {
      include: [ "@auth/core" ]
    }**
  };
});

Enter fullscreen mode Exit fullscreen mode

In this tutorial we will work with GitHub as our provider, so after installing Auth.js we will find that it added a file called: plugin@auth.ts:

import { serverAuth$ } from '@builder.io/qwik-auth';
import GitHub from '@auth/core/providers/github';
import type { Provider } from '@auth/core/providers';

export const { onRequest, useAuthSession, useAuthSignin, useAuthSignout } = serverAuth$(
  ({ env }) => ({
    secret: env.get('AUTH_SECRET'),
    trustHost: true,
    providers: [
      GitHub({
        clientId: env.get('GITHUB_ID')!,
        clientSecret: env.get('GITHUB_SECRET')!,
      }),
    ] as Provider[],
  })
);
Enter fullscreen mode Exit fullscreen mode

Connecting to Github

In the file: plugin@auth.ts, we had some variables that we should define in our application AUTH_SECRET, GITHUB_ID and GITHUB_SECRET. To do that, we should create a file .env.local :

GITHUB_ID=*********************
GITHUB_SECRET=****************************
AUTH_SECRET=***********************************
Enter fullscreen mode Exit fullscreen mode

To generate the AUTH_SECRET we can use this website: https://generate-secret.vercel.app/32

To generate the GITHUB_ID and GITHUB_SECRET we should go to our GitHub: Setting ⇒ Developer Setting ⇒ OAuth Apps, and we should create a new Auth App:

Image description

The result we are the generation of GITHUB_ID and GITHUB_SECRET.

Final Integration in our Code

Auth.js provides us with multiple functions that will simplify for us the process of authentication:

  • useAuthSignin: it is a function that returns the action of sign-in to start the flow of authentication with redirection to a page with all the possible ways to sign in, example:
  • useAuthSession: if we are not connected, it will return an empty object, but if we are connected, it will return a session object that contains multiple information, exemple:
  • useAuthSignout: it is a function that provides us an action of signing out from our application, so all the parameters and objects that concern our session will be removed, example:

import { component$ } from '@builder.io/qwik';
import { QwikLogo } from '../icons/qwik';
import styles from './header.module.css';
import { useAuthSignin, useAuthSession, useAuthSignout } from '~/routes/plugin@auth';

export default component$(() => {
  const signIn = useAuthSignin();
    const session = useAuthSession();
  const signOut = useAuthSignout();


  return (
    <header class={styles.header}>
      <div class={['container', styles.wrapper]}>
        <div class={styles.logo}>
          <a href="/" title="qwik">
            <QwikLogo height={50} width={143} />
          </a>
        </div>
        <ul>
          <li>
            <a href="https://qwik.builder.io/docs/components/overview/" target="_blank">
              Docs
            </a>
          </li>
          <li>
            <a href="https://qwik.builder.io/examples/introduction/hello-world/" target="_blank">
              Examples
            </a>
          </li>
          <li>
            <a href="https://qwik.builder.io/tutorial/welcome/overview/" target="_blank">
              Tutorials
            </a>
          </li>
          <li>
            <span>
              {session.value?.user?.email}
            </span>
          </li>
          <li>
            {session.value?.user === undefined && <button onClick$={() => signIn.submit({ providerId: 'github', options: { callbackUrl: 'http://localhost:5173/' } })}>Sign In</button>}
          </li>
          <li>
            {session.value?.user !== undefined && <button onClick$={() => signOut.submit({ callbackUrl: '/' })}>Sign Out</button>}
          </li>
        </ul>
      </div>
    </header>
  );
});

Enter fullscreen mode Exit fullscreen mode

In the code above, we have a header that will have a button to sign in that we will show only if we are not connected:

Image description

So if we sign in successfully the button will disappear, and we will show the sign-out button with the user email in the header:

Image description

Top comments (0)