Add google Auth

This commit is contained in:
MartinBraquet
2025-07-27 00:32:56 +02:00
parent e970713dcc
commit 7741de2a1c
6 changed files with 203 additions and 2 deletions

1
.gitignore vendored
View File

@@ -47,3 +47,4 @@ notebooks
martin
/src/generated/prisma
*.db

View File

@@ -0,0 +1,89 @@
# Google OAuth Setup Guide
## Prerequisites
1. A Google Cloud Platform (GCP) account
2. A GCP project with the Google+ API enabled
3. OAuth consent screen configured
## Step 1: Create OAuth Credentials
1. Go to the [Google Cloud Console](https://console.cloud.google.com/)
2. Select your project or create a new one
3. Navigate to "APIs & Services" > "Credentials"
4. Click "Create Credentials" and select "OAuth client ID"
## Step 2: Configure OAuth Consent Screen
1. If you haven't configured the consent screen, click "Configure Consent Screen"
2. Choose "External" user type and click "Create"
3. Fill in the required app information:
- App name (e.g., "My App")
- User support email (your email)
- Developer contact information (your email)
4. Click "Save and Continue"
5. Skip the "Scopes" step (we'll use the default scopes)
6. Add test users (your email) if you're in testing mode
7. Click "Save and Continue"
## Step 3: Create OAuth Client ID
1. Go back to "Credentials"
2. Click "Create Credentials" > "OAuth client ID"
3. Select "Web application" as the application type
4. Enter a name (e.g., "Web Client")
5. Under "Authorized JavaScript origins", add:
- `http://localhost:3000`
- `http://localhost:3001`
6. Under "Authorized redirect URIs", add:
- `http://localhost:3000/api/auth/callback/google`
- `http://localhost:3001/api/auth/callback/google`
7. Click "Create"
## Step 4: Set Up Environment Variables
Create or update your `.env.local` file with the following variables:
```env
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-secret-key-here # Generate with: openssl rand -base64 32
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
DATABASE_URL=file:./dev.db
```
## Step 5: Update Database Schema
Run the following command to update your database schema:
```bash
npx prisma db push
```
## Step 6: Restart Your Development Server
```bash
npm run dev
```
## Testing Google OAuth
1. Visit the login page at `http://localhost:3000/login`
2. Click the "Sign in with Google" button
3. You should be redirected to Google's sign-in page
4. After signing in, you'll be redirected back to your app
## Troubleshooting
- If you get a "redirect_uri_mismatch" error, double-check the Authorized Redirect URIs in your Google Cloud Console
- Make sure the Google+ API is enabled in your GCP project
- Check your browser's console and network tab for any errors
- Ensure your `.env.local` file has the correct values and is in the root of your project
## Production Deployment
When deploying to production:
1. Update the `NEXTAUTH_URL` to your production URL
2. Add your production domain to the Authorized JavaScript origins and redirect URIs in the Google Cloud Console
3. Ensure your production environment has the same environment variables set
4. Consider using a more secure database than SQLite for production

83
scripts/setup-env.js Executable file
View File

@@ -0,0 +1,83 @@
const fs = require('fs');
const path = require('path');
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
// Check if .env.local exists, if not create it
const envPath = path.join(__dirname, '../.env.local');
const questions = [
{
name: 'NEXTAUTH_SECRET',
message: 'Enter a secure random string for NEXTAUTH_SECRET (you can generate one with `openssl rand -base64 32`): ',
validate: input => input.length >= 32 || 'Secret must be at least 32 characters long'
},
{
name: 'NEXTAUTH_URL',
message: 'Enter your NEXTAUTH_URL (e.g., http://localhost:3000): ',
default: 'http://localhost:3000',
validate: input => input.startsWith('http') || 'Must be a valid URL starting with http:// or https://'
},
{
name: 'GOOGLE_CLIENT_ID',
message: 'Enter your Google OAuth Client ID: ',
validate: input => !!input || 'Google Client ID is required'
},
{
name: 'GOOGLE_CLIENT_SECRET',
message: 'Enter your Google OAuth Client Secret: ',
validate: input => !!input || 'Google Client Secret is required'
}
];
async function setupEnv() {
console.log('Setting up your environment variables...\n');
let envVars = [];
for (const q of questions) {
const answer = await new Promise((resolve) => {
const ask = () => {
readline.question(q.message, (input) => {
const value = input.trim() || q.default || '';
if (q.validate) {
const validation = q.validate(value);
if (validation !== true) {
console.log(validation);
return ask();
}
}
resolve(value);
});
};
ask();
});
envVars.push(`${q.name}=${answer}`);
}
// Add any additional environment variables
envVars.push('DATABASE_URL=file:./dev.db');
// Write to .env.local
fs.writeFileSync(envPath, envVars.join('\n') + '\n');
console.log('\n✅ Environment variables have been saved to .env.local');
console.log('\nNext steps:');
console.log('1. Run `npx prisma db push` to update your database schema');
console.log('2. Restart your development server with `npm run dev`\n');
readline.close();
}
// Create .env.local if it doesn't exist
if (!fs.existsSync(envPath)) {
setupEnv();
} else {
console.log('.env.local already exists. Please update it with the following variables:');
console.log(questions.map(q => `${q.name}=`).join('\n'));
console.log('\nYou can also delete .env.local and run this script again to create it interactively.');
readline.close();
}

View File

@@ -24,7 +24,7 @@ export default function DashboardPage() {
}
if (status === 'unauthenticated') {
router.push('/login');
// router.push('/login');
return null;
}

View File

@@ -1,5 +1,7 @@
import type { NextAuthConfig } from 'next-auth';
import Credentials from 'next-auth/providers/credentials';
import Google from 'next-auth/providers/google';
import { PrismaAdapter } from '@auth/prisma-adapter';
import { prisma } from './lib/prisma';
import { compare } from 'bcryptjs';
@@ -37,7 +39,21 @@ export const authConfig = {
return session;
},
},
adapter: PrismaAdapter(prisma),
providers: [
Google({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
allowDangerousEmailAccountLinking: true,
profile(profile) {
return {
id: profile.sub,
name: profile.name,
email: profile.email,
image: profile.picture,
};
},
}),
Credentials({
name: 'Credentials',
credentials: {
@@ -80,4 +96,16 @@ export const authConfig = {
},
secret: process.env.NEXTAUTH_SECRET,
trustHost: true,
debug: process.env.NODE_ENV === 'development',
cookies: {
sessionToken: {
name: `__Secure-next-auth.session-token`,
options: {
httpOnly: true,
sameSite: 'lax',
path: '/',
secure: process.env.NODE_ENV === 'production',
},
},
},
} satisfies NextAuthConfig;

View File

@@ -5,7 +5,7 @@ declare global {
var prisma: PrismaClient | undefined;
}
const globalForPrisma = global as unknown as { prisma: PrismaClient };
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
export const prisma = globalForPrisma.prisma || new PrismaClient();