Auth
Sign In
Authenticate existing users
Sign In
Authenticate an existing user and receive authentication tokens.
Endpoint
POST /v1/signinRequest Headers
| Header | Type | Required | Description |
|---|---|---|---|
x-api-key | string | Yes | Your API key |
Content-Type | string | Yes | Must be application/json |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | User's email address (valid email format) |
password | string | Yes | User's password (minimum 8 characters) |
Response
Success Response (200)
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": "user_123",
"name": "John Doe",
"email": "[email protected]",
"createdAt": "2024-01-15T10:30:00Z"
}
}Error Responses
| Code | Description |
|---|---|
| 401 | Invalid or missing API key |
| 422 | Invalid input data (invalid email format or password too short) |
| 500 | Server error |
Examples
interface SignInRequest {
email: string;
password: string;
}
interface SignInResponse {
token: string;
user: {
id: string;
name: string;
email: string;
createdAt: string;
};
}
async function signIn(credentials: SignInRequest): Promise<SignInResponse> {
const response = await fetch('https://api.yourstore.com/v1/signin', {
method: 'POST',
headers: {
'x-api-key': process.env.NEXT_PUBLIC_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify(credentials),
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'Sign in failed');
}
return response.json();
}
// Usage
try {
const result = await signIn({
email: '[email protected]',
password: 'SecurePass123',
});
console.log('Logged in:', result.user.name);
// Store token and user data in cookies/localStorage
} catch (error) {
console.error('Sign in error:', error);
}async function signIn(credentials) {
const response = await fetch('https://api.yourstore.com/v1/signin', {
method: 'POST',
headers: {
'x-api-key': process.env.NEXT_PUBLIC_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify(credentials),
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'Sign in failed');
}
return response.json();
}
// Usage
signIn({
email: '[email protected]',
password: 'SecurePass123',
})
.then(result => {
console.log('Logged in:', result.user.name);
// Store token and user data
})
.catch(error => {
console.error('Sign in error:', error);
});'use server'
import { cookies } from 'next/headers';
import { redirect } from 'next/navigation';
export async function signInAction(formData: FormData) {
const email = formData.get('email') as string;
const password = formData.get('password') as string;
try {
const response = await fetch('https://api.yourstore.com/v1/signin', {
method: 'POST',
headers: {
'x-api-key': process.env.BACKEND_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, password }),
});
if (!response.ok) {
return { error: 'Invalid credentials' };
}
const data = await response.json();
// Store auth token
const cookieStore = await cookies();
cookieStore.set('auth_token', data.token, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
maxAge: 60 * 60 * 24 * 90, // 90 days
});
// Store user data
cookieStore.set('user_data', JSON.stringify(data.user), {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
maxAge: 60 * 60 * 24 * 90,
});
// Clear guest token if exists
cookieStore.delete('guest_token');
} catch (error) {
return { error: 'Something went wrong' };
}
redirect('/dashboard');
}Using the Cookie Manager
If you're using the provided CookieManager utility:
'use server'
import { cookieManager } from '@/lib/auth-tools';
export async function signInAction(email: string, password: string) {
const response = await fetch('https://api.yourstore.com/v1/signin', {
method: 'POST',
headers: {
'x-api-key': process.env.BACKEND_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, password }),
});
if (!response.ok) {
throw new Error('Sign in failed');
}
const loginResponse = await response.json();
// This automatically stores tokens and clears guest token
await cookieManager.setAuthenticatedUser(loginResponse);
return loginResponse.user;
}After successful sign-in, remember to call the Merge Guest Data endpoint if the user had items in their cart or wishlist before logging in.
Client-Side Form Example
'use client'
import { useState } from 'react';
import { signInAction } from '@/actions/auth';
export default function SignInForm() {
const [error, setError] = useState('');
const [loading, setLoading] = useState(false);
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
setLoading(true);
setError('');
const formData = new FormData(e.currentTarget);
const result = await signInAction(formData);
if (result?.error) {
setError(result.error);
setLoading(false);
}
}
return (
<form onSubmit={handleSubmit}>
<input
type="email"
name="email"
placeholder="Email"
required
/>
<input
type="password"
name="password"
placeholder="Password"
minLength={8}
required
/>
{error && <p className="error">{error}</p>}
<button type="submit" disabled={loading}>
{loading ? 'Signing in...' : 'Sign In'}
</button>
</form>
);
}Best Practices
Security Considerations:
- Always use HTTPS in production
- Store tokens in httpOnly cookies, never in localStorage
- Implement rate limiting on the client side
- Clear sensitive form data after submission
Validation
Always validate input on the client side before making the request:
function validateSignIn(email: string, password: string) {
const errors: string[] = [];
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
errors.push('Valid email is required');
}
if (!password || password.length < 8) {
errors.push('Password must be at least 8 characters');
}
return errors;
}Next Steps
After signing in:
- Merge guest data to transfer cart and wishlist items
- Redirect user to their dashboard or previous page
- Update UI to show authenticated state