Back to blogs
Blog
Writing in public
Longer posts — published here first, then cross-posted to Dev.to with a canonical URL back to this site.
Blog
Longer posts — published here first, then cross-posted to Dev.to with a canonical URL back to this site.
Back to blogs
Back to blogs
Postnextjs, authjs, oauth, typescript
You can select the scopes you want to request from GitHub/your oauthprovider in the login page, and...
Date published

Modify your nextauth client and add a callbacks section that will get the access token from the...

Why You Might Still Pick Next.js Over TanStack Start From a TanStack Start...

A guide to creating Android home screen widgets using Expo modules, complete with state management,...
You can select the scopes you want to request from GitHub/your oauthprovider in the login page, and then the scopes will be passed to the OAuth provider.
firstly look up th eoauth scopes allowed for example the github ones are oauth scopes documentation
then we can do it in 2 ways
1import NextAuth from "next-auth";2import GitHub from "next-auth/providers/github";34export const githubScopes = ["user", "repo", "delete_repo"] as const;56export const { handlers, signIn, signOut, auth } = NextAuth({7 pages: {8 signIn: "/auth",9 },10 providers: [11 GitHub({12 authorization: {13 params: {14 scope: githubScopes.join(" "),15 },16 },17 }),18 ],19 debug: true,20 callbacks: {21 authorized: async ({ auth }) => {22 // Logged in users are authenticated, otherwise redirect to login page23 return !!auth;24 },25 },26});
use the signin for client side login , and make sure the component has a "use client" directive
1"use client";2import { signIn } from "next-auth/react";3import { useState } from "react";4import { FaGithub } from "react-icons/fa";56interface OauthButtonProps {}78export function OauthButton({}: OauthButtonProps) {9 const [selectedScopes, setSelectedScopes] = useState<string[]>([]);1011 const scopeOptions = [12 {13 id: "user",14 label: "User Profile",15 description: "Read/Write access to profile info",16 },17 {18 id: "repo",19 label: "Repository Access",20 description: "Full control of public and private repositories",21 },22 {23 id: "delete_repo",24 label: "Delete Repositories",25 description: "Ability to delete repositories",26 },27 ];2829 const handleScopeToggle = (scope: string) => {30 setSelectedScopes((prev) =>31 prev.includes(scope) ? prev.filter((s) => s !== scope) : [...prev, scope]32 );33 };3435 return (36 <div className="w-full flex flex-col justify-center items-center gap-5">37 <div className=" flex flex-col justify-center items-center gap-2">38 {selectedScopes.length === 0 && (39 <div role="alert" className="alert alert-info alert-outline">40 <span className="text-xs text-center">41 if no scopes are selected,42 the default read-only access to public information will be used43 </span>44 </div>45 )}46 {scopeOptions.map((scope) => (47 <label48 key={scope.id}49 className="flex w-full bg-primary/10 items-start space-x-3 p-3 rounded-lg hover:bg-base-300 transition-colors">50 <input51 type="checkbox"52 className="checkbox checkbox-accent mt-1 border border-accent"53 checked={selectedScopes.includes(scope.id)}54 onChange={() => handleScopeToggle(scope.id)}55 />56 <div className="flex flex-col">57 <span className="font-medium">{scope.label}</span>58 <span className="text-sm text-base-content/70">{scope.description}</span>59 </div>60 </label>61 ))}62 </div>63 <button64 className="btn btn-wide btn-accent w-full"65 onClick={() =>66 signIn(67 "github",68 {},69 {70 scope: selectedScopes.join(" ") || undefined,71 }72 )73 }>74 <FaGithub className="h-5 w-5" />75 Sign in with GitHub76 </button>77 </div>78 );79}80
>[!NOTE]
The scopes should be a space separated string , eg "repo user delete_repo"