very first commit
This commit is contained in:
376
HOW_TO_USE.md
Normal file
376
HOW_TO_USE.md
Normal file
@@ -0,0 +1,376 @@
|
||||
# How to Use Auth Service in Your Projects
|
||||
|
||||
Step-by-step guide for integrating the authentication service into Dexar, Novo Markets, FastCheck, and BackOffice.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### 1. Add Environment Configuration
|
||||
|
||||
In each project, add auth service URL to your environment files:
|
||||
|
||||
**`src/environments/environment.ts`** (Development):
|
||||
```typescript
|
||||
export const environment = {
|
||||
production: false,
|
||||
authServiceUrl: 'http://localhost:4300',
|
||||
apiUrl: 'http://localhost:3000/api',
|
||||
projectId: 'dexar' // Change per project: dexar/novo/fastcheck/backoffice
|
||||
};
|
||||
```
|
||||
|
||||
**`src/environments/environment.production.ts`**:
|
||||
```typescript
|
||||
export const environment = {
|
||||
production: true,
|
||||
authServiceUrl: 'https://auth.dx-projects.com',
|
||||
apiUrl: 'https://api.dx-projects.com/api',
|
||||
projectId: 'dexar'
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📁 Files to Create
|
||||
|
||||
### Step 1: Create Auth Interceptor
|
||||
|
||||
**File:** `src/app/interceptors/auth.interceptor.ts`
|
||||
|
||||
```typescript
|
||||
import { HttpInterceptorFn } from '@angular/common/http';
|
||||
import { inject } from '@angular/core';
|
||||
import { catchError, throwError } from 'rxjs';
|
||||
import { environment } from '../../environments/environment';
|
||||
|
||||
export const authInterceptor: HttpInterceptorFn = (req, next) => {
|
||||
const token = localStorage.getItem('authToken');
|
||||
|
||||
// Add token to API requests
|
||||
if (token && req.url.includes(environment.apiUrl)) {
|
||||
req = req.clone({
|
||||
setHeaders: { Authorization: `Bearer ${token}` }
|
||||
});
|
||||
}
|
||||
|
||||
return next(req).pipe(
|
||||
catchError((error) => {
|
||||
// Redirect to auth service on 401
|
||||
if (error.status === 401) {
|
||||
localStorage.removeItem('authToken');
|
||||
const currentUrl = window.location.href;
|
||||
window.location.href = `${environment.authServiceUrl}/login?project=${environment.projectId}&redirect=${encodeURIComponent(currentUrl)}`;
|
||||
}
|
||||
return throwError(() => error);
|
||||
})
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
### Step 2: Create Auth Guard
|
||||
|
||||
**File:** `src/app/guards/auth.guard.ts`
|
||||
|
||||
```typescript
|
||||
import { inject } from '@angular/core';
|
||||
import { CanActivateFn } from '@angular/router';
|
||||
import { environment } from '../../environments/environment';
|
||||
|
||||
export const authGuard: CanActivateFn = () => {
|
||||
const token = localStorage.getItem('authToken');
|
||||
|
||||
if (token) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Redirect to auth service
|
||||
const currentUrl = window.location.href;
|
||||
window.location.href = `${environment.authServiceUrl}/login?project=${environment.projectId}&redirect=${encodeURIComponent(currentUrl)}`;
|
||||
|
||||
return false;
|
||||
};
|
||||
```
|
||||
|
||||
### Step 3: Update App Config
|
||||
|
||||
**File:** `src/app/app.config.ts`
|
||||
|
||||
```typescript
|
||||
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
|
||||
import { provideRouter } from '@angular/router';
|
||||
import { provideHttpClient, withInterceptors } from '@angular/common/http';
|
||||
import { routes } from './app.routes';
|
||||
import { authInterceptor } from './interceptors/auth.interceptor';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
provideZoneChangeDetection({ eventCoalescing: true }),
|
||||
provideRouter(routes),
|
||||
provideHttpClient(withInterceptors([authInterceptor]))
|
||||
]
|
||||
};
|
||||
```
|
||||
|
||||
### Step 4: Handle Auth Callback in App Component
|
||||
|
||||
**Update:** `src/app/app.ts` or `src/app/app.component.ts`
|
||||
|
||||
```typescript
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Router, RouterOutlet } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
imports: [RouterOutlet],
|
||||
template: '<router-outlet />',
|
||||
styleUrls: ['./app.scss']
|
||||
})
|
||||
export class App implements OnInit {
|
||||
constructor(private router: Router) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
// Handle token from auth service redirect
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const token = urlParams.get('token');
|
||||
|
||||
if (token) {
|
||||
localStorage.setItem('authToken', token);
|
||||
// Clean URL
|
||||
window.history.replaceState({}, document.title, window.location.pathname);
|
||||
// Navigate to dashboard
|
||||
this.router.navigate(['/dashboard']);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 5: Protect Routes
|
||||
|
||||
**Update:** `src/app/app.routes.ts`
|
||||
|
||||
```typescript
|
||||
import { Routes } from '@angular/router';
|
||||
import { authGuard } from './guards/auth.guard';
|
||||
|
||||
export const routes: Routes = [
|
||||
{
|
||||
path: 'dashboard',
|
||||
loadComponent: () => import('./pages/dashboard/dashboard.component'),
|
||||
canActivate: [authGuard] // ✅ Protected route
|
||||
},
|
||||
{
|
||||
path: 'products',
|
||||
loadComponent: () => import('./pages/products/products.component'),
|
||||
canActivate: [authGuard] // ✅ Protected route
|
||||
},
|
||||
// ... more protected routes
|
||||
];
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Project-Specific Integration
|
||||
|
||||
### For Dexar (marketplaces):
|
||||
```typescript
|
||||
// src/environments/environment.ts
|
||||
export const environment = {
|
||||
production: false,
|
||||
authServiceUrl: 'http://localhost:4300',
|
||||
apiUrl: 'http://localhost:3000/api',
|
||||
projectId: 'dexar'
|
||||
};
|
||||
```
|
||||
|
||||
### For Novo Markets:
|
||||
```typescript
|
||||
// src/environments/environment.novo.ts
|
||||
export const environment = {
|
||||
production: false,
|
||||
authServiceUrl: 'http://localhost:4300',
|
||||
apiUrl: 'http://localhost:3000/api',
|
||||
projectId: 'novo',
|
||||
brandName: 'Novo'
|
||||
};
|
||||
```
|
||||
|
||||
### For FastCheck:
|
||||
```typescript
|
||||
// FastCheck/src/environments/environment.ts
|
||||
export const environment = {
|
||||
production: false,
|
||||
authServiceUrl: 'http://localhost:4300',
|
||||
apiUrl: 'http://localhost:3000/api',
|
||||
projectId: 'fastcheck'
|
||||
};
|
||||
```
|
||||
|
||||
### For BackOffice:
|
||||
```typescript
|
||||
// market-backOffice/src/environments/environment.ts
|
||||
export const environment = {
|
||||
production: false,
|
||||
authServiceUrl: 'http://localhost:4300',
|
||||
apiUrl: 'http://localhost:3000/api',
|
||||
projectId: 'backoffice'
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Testing Integration
|
||||
|
||||
### Test Flow:
|
||||
|
||||
1. **Clear localStorage:**
|
||||
```javascript
|
||||
localStorage.removeItem('authToken');
|
||||
```
|
||||
|
||||
2. **Navigate to protected route:**
|
||||
```
|
||||
http://localhost:4200/dashboard
|
||||
```
|
||||
|
||||
3. **Should redirect to:**
|
||||
```
|
||||
http://localhost:4300/login?project=dexar&redirect=http://localhost:4200/dashboard
|
||||
```
|
||||
|
||||
4. **After authentication, returns to:**
|
||||
```
|
||||
http://localhost:4200/dashboard?token=eyJ...
|
||||
```
|
||||
|
||||
5. **Token stored, URL cleaned automatically**
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Optional: Logout Functionality
|
||||
|
||||
### Create Auth Service
|
||||
|
||||
**File:** `src/app/services/auth.service.ts`
|
||||
|
||||
```typescript
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { environment } from '../../environments/environment';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AuthService {
|
||||
private http = inject(HttpClient);
|
||||
|
||||
logout(): void {
|
||||
const token = localStorage.getItem('authToken');
|
||||
|
||||
if (token) {
|
||||
this.http.post(`${environment.apiUrl}/auth/logout`, {
|
||||
deviceInfo: this.getDeviceInfo()
|
||||
}).subscribe({
|
||||
complete: () => this.clearAuth(),
|
||||
error: () => this.clearAuth()
|
||||
});
|
||||
} else {
|
||||
this.clearAuth();
|
||||
}
|
||||
}
|
||||
|
||||
private clearAuth(): void {
|
||||
localStorage.removeItem('authToken');
|
||||
window.location.href = `${environment.authServiceUrl}/login?project=${environment.projectId}`;
|
||||
}
|
||||
|
||||
private getDeviceInfo() {
|
||||
return {
|
||||
deviceType: window.innerWidth < 768 ? 'mobile' : 'desktop',
|
||||
deviceOS: null,
|
||||
context: 'browser',
|
||||
project: environment.projectId
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Use in Component:
|
||||
|
||||
```typescript
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { AuthService } from './services/auth.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-header',
|
||||
template: `<button (click)="logout()">Logout</button>`
|
||||
})
|
||||
export class HeaderComponent {
|
||||
private authService = inject(AuthService);
|
||||
|
||||
logout(): void {
|
||||
this.authService.logout();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 Summary
|
||||
|
||||
**3 Files to Create:**
|
||||
1. ✅ `interceptors/auth.interceptor.ts`
|
||||
2. ✅ `guards/auth.guard.ts`
|
||||
3. ✅ Update `app.config.ts`
|
||||
|
||||
**1 File to Modify:**
|
||||
4. ✅ Update `app.ts` (handle token callback)
|
||||
|
||||
**1 Environment Update:**
|
||||
5. ✅ Add `authServiceUrl` and `projectId`
|
||||
|
||||
**That's it!** Your project now uses centralized authentication! 🎉
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Deployment
|
||||
|
||||
1. **Deploy Auth Service:**
|
||||
```bash
|
||||
cd auth-service
|
||||
npm run build:prod
|
||||
# Deploy to auth.dx-projects.com
|
||||
```
|
||||
|
||||
2. **Update Production Environments:**
|
||||
```typescript
|
||||
authServiceUrl: 'https://auth.dx-projects.com'
|
||||
```
|
||||
|
||||
3. **Configure CORS on Backend:**
|
||||
- Allow `http://localhost:4300` (dev)
|
||||
- Allow `https://auth.dx-projects.com` (prod)
|
||||
- Allow all project domains
|
||||
|
||||
---
|
||||
|
||||
## ❓ Troubleshooting
|
||||
|
||||
### Infinite redirect loop?
|
||||
- Ensure auth guard doesn't protect callback routes
|
||||
- Check that token is being stored correctly
|
||||
|
||||
### Token not saved?
|
||||
- Check browser console for errors
|
||||
- Verify localStorage is available
|
||||
- Check URL parameters parsing
|
||||
|
||||
### CORS errors?
|
||||
- Backend must allow auth service domain
|
||||
- Check CORS configuration
|
||||
|
||||
---
|
||||
|
||||
## 📚 More Documentation
|
||||
|
||||
- **Backend API:** See `BACKEND_API.md`
|
||||
- **Project Setup:** See `README.md`
|
||||
- **Support:** backend@dx-projects.com
|
||||
Reference in New Issue
Block a user