-
Notifications
You must be signed in to change notification settings - Fork 156
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* init * docs: update fr docs * fix: path nuxt-i18n issue * fix(navigation): use `route.params.pathMatch` * fix(navigation): use `app.i18n.locale` * fix: lint * fix: use Docus translations * fix: typo
- Loading branch information
Showing
266 changed files
with
28,508 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
--- | ||
title: Données asynchrones | ||
description: Exemple de données asynchrones avec Nuxt.js | ||
github: async-data | ||
documentation: /docs/2.x/features/data-fetching#async-data | ||
category: advanced | ||
position: 41 | ||
--- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
--- | ||
title: API d'authentification externe (JWT) | ||
description: Exemple d'authentification avec le service d'API externe (jsonwebtoken) avec Nuxt.js | ||
github: auth-jwt | ||
code: https://github.com/ahadyekta/nuxt-auth-external-jwt | ||
category: advanced | ||
position: 43 | ||
--- | ||
|
||
# Documentation | ||
|
||
Dans l'exemple auth-routes l'API et le site Nuxt se lancent ensemble et utilisent la même instance serveur Node.js. Cependant, il est parfois mieux de travailler avec une API externe avec jsonWebToken. Cela sera expliqué simplement à travers cet exemple. | ||
|
||
## Module officiel `auth-module` | ||
|
||
Si vous souhaitez implémenter un flux d'authentification complexe, par exemple OAuth2, nous suggérons d'utiliser le module officiel [`auth-module`](https://github.com/nuxt-community/auth-module) | ||
|
||
## Official `auth-module` | ||
|
||
If you want to implement complex authentication flows, for example OAuth2, we suggest using the official [`auth-module`](https://github.com/nuxt-community/auth-module) | ||
|
||
## Structure | ||
|
||
Puisque Nuxt.js fournit à la fois le rendu client et serveur ainsi qu'un cookie différent entre le navigateur et le serveur Node.js, nous devons fournir un jeton de donnée qui puisse être accessible par les deux parties. | ||
|
||
### Pour le rendu serveur | ||
|
||
Nous devons sauvegarder le jeton dans un cookie de session après connexion pour qu'il puisse être récupéré via `req.headers.cookie` par les fichiers middlewares, la fonction `nuxtServerInit` ou tout ce qui a accès à `req`. | ||
|
||
### Pour le rendu client | ||
|
||
Nous actons directement le jeton dans le store, aussi longtemps que la page n'est pas fermée ou rechargée, nous avons le jeton. | ||
|
||
Tout d'abord, installons les dépendances : | ||
|
||
```bash | ||
npm install js-cookie --save | ||
npm install cookieparser --save | ||
``` | ||
|
||
## Page de connexion | ||
|
||
À l'intérieur du dossier des pages, créez un fichier `login.vue` et dans ce fichier, dans la partie script, ajoutez : | ||
|
||
```js | ||
const Cookie = process.client ? require('js-cookie') : undefined | ||
|
||
export default { | ||
middleware: 'notAuthenticated', | ||
methods: { | ||
postLogin() { | ||
setTimeout(() => { | ||
// nous simulons la requête asynchrone avec un timeout. | ||
const auth = { | ||
accessToken: 'uneChaineObtenueDuServiceApiAVecAjax' | ||
} | ||
this.$store.commit('setAuth', auth) // muter `auth` dans le store pour le rendu client | ||
Cookie.set('auth', auth) // sauver le jeton dans un cookie pour le rendu serveur | ||
this.$router.push('/') | ||
}, 1000) | ||
} | ||
} | ||
} | ||
``` | ||
|
||
> Note : nous simulerons la requête asynchrone avec un délai. | ||
## Utiliser le store | ||
|
||
Après cela modifiez `index.js` dans le dossier `store` comme ci-dessous : | ||
|
||
```javascript | ||
import Vuex from 'vuex' | ||
|
||
const cookieparser = process.server ? require('cookieparser') : undefined | ||
|
||
const createStore = () => { | ||
return new Vuex.Store({ | ||
state: () => ({ | ||
auth: null | ||
}), | ||
mutations: { | ||
setAuth(state, auth) { | ||
state.auth = auth | ||
} | ||
}, | ||
actions: { | ||
nuxtServerInit({ commit }, { req }) { | ||
let auth = null | ||
if (req.headers.cookie) { | ||
const parsed = cookieparser.parse(req.headers.cookie) | ||
try { | ||
auth = JSON.parse(parsed.auth) | ||
} catch (err) { | ||
// aucun cookie valide trouvé | ||
} | ||
} | ||
commit('setAuth', auth) | ||
} | ||
} | ||
}) | ||
} | ||
|
||
export default createStore | ||
``` | ||
|
||
> Note : la fonction `nuxtServerInit` s'exécute seulement dans chaque rendu côté serveur. Nous l'utilisons pour muter le cookie de session du navigateur dans le store. Nous pouvons récupérer le cookie de session du navigateur avec `req.headers.cookie` et l'analyser en utilisant `cookieparser`. | ||
## Authentification vérifiée via middlewares | ||
|
||
Nous pouvons vérifier le store pour obtenir un accès au jeton sur toutes les pages qui demandent un accès limité. Dans le dossier des middlewares nous créons un fichier `authenticated.js` : | ||
|
||
```javascript | ||
export default function ({ store, redirect }) { | ||
// Si l'utilisateur n'est pas authentifié | ||
if (!store.state.auth) { | ||
return redirect('/login') | ||
} | ||
} | ||
``` | ||
|
||
et dans le dossier des middlewares créez un fichier `notAuthenticated.js` pour la page de connexion : | ||
|
||
```javascript | ||
export default function ({ store, redirect }) { | ||
// Si l'utilisateur est authentifié, aller à la page d'accueil | ||
if (store.state.auth) { | ||
return redirect('/') | ||
} | ||
} | ||
``` | ||
|
||
> Note: utilisez le middleware `authenticated` pour les pages nécessitant une authentification et utilisez le middleware `notAuthenticated` pour les pages login/register et similaires. | ||
## Déconnecter l'utilisateur | ||
|
||
Enfin pour laisser l'utilisateur pouvoir se déconnecter du système, nous pouvons retirer le cookie : | ||
|
||
```javascript | ||
const Cookie = process.client ? require('js-cookie') : undefined | ||
|
||
export default { | ||
methods: { | ||
logout() { | ||
// Un code sera également requis pour invalider le cookie JWT sur une API externe | ||
Cookie.remove('auth') | ||
this.$store.commit('setAuth', null) | ||
} | ||
} | ||
} | ||
``` | ||
|
||
> Note: se référer à la méthode en utilisant @click="logout" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,230 @@ | ||
--- | ||
title: Authentification de routes | ||
description: Exemple d'authentification de routes avec Nuxt.js | ||
github: auth-routes | ||
livedemo: https://nuxt-auth-routes.gomix.me | ||
liveedit: https://gomix.com/#!/project/nuxt-auth-routes | ||
category: advanced | ||
position: 42 | ||
--- | ||
|
||
# Documentation | ||
|
||
> Nuxt.js peut être utilisé pour créer facilement des routes authentifiées. | ||
## Module officiel `auth-module` | ||
|
||
Si vous souhaitez implémenter des flux d'authentification complexes, par exemple OAuth2, nous vous suggérons d'utiliser la fonction officielle [`auth-module`](https://github.com/nuxt-community/auth-module) | ||
|
||
## Avec Express et Sessions | ||
|
||
Si vous souhaitez implémenter un flux d'authentification complexe, par exemple OAuth2, nous suggérons d'utiliser le module officiel [`auth-module`](https://github.com/nuxt-community/auth-module) | ||
|
||
## Utilisation de Express et des sessions | ||
|
||
Pour ajouter la fonctionnalité de sessions dans notre application, nous utiliserons `express` et `express-session`. Pour cela, nous devons utiliser Nuxt.js de manière programmatique. | ||
|
||
Premièrement, nous installons les dépendances : | ||
|
||
```bash | ||
yarn add express express-session body-parser whatwg-fetch | ||
``` | ||
|
||
_Nous parlerons de `whatwg-fetch` plus loin._ | ||
|
||
Puis nous créons notre `server.js` : | ||
|
||
```js | ||
const { Nuxt, Builder } = require('nuxt') | ||
const bodyParser = require('body-parser') | ||
const session = require('express-session') | ||
const app = require('express')() | ||
|
||
// Analyse du corps de requête pour y accéder via `req.body` | ||
app.use(bodyParser.json()) | ||
|
||
// Mise en place de sessions pour y accéder via `req.session` | ||
app.use( | ||
session({ | ||
secret: 'cle-super-secrete', | ||
resave: false, | ||
saveUninitialized: false, | ||
cookie: { maxAge: 60000 } | ||
}) | ||
) | ||
|
||
// Accès à `/api/login` en POST pour connecter l'utilisateur et l'ajouter à `req.session.authUser` | ||
app.post('/api/login', function (req, res) { | ||
if (req.body.username === 'demo' && req.body.password === 'demo') { | ||
req.session.authUser = { username: 'demo' } | ||
return res.json({ username: 'demo' }) | ||
} | ||
res.status(401).json({ error: 'Mauvaise authentification' }) | ||
}) | ||
|
||
// Accès à `/api/logout` en POST pour déconnecter l'utilisateur et le retirer de `req.session` | ||
app.post('/api/logout', function (req, res) { | ||
delete req.session.authUser | ||
res.json({ ok: true }) | ||
}) | ||
|
||
// Nous instancions Nuxt.js avec les options | ||
const isProd = process.env.NODE_ENV === 'production' | ||
const nuxt = new Nuxt({ dev: !isProd }) | ||
// Pas de build en production | ||
if (!isProd) { | ||
const builder = new Builder(nuxt) | ||
builder.build() | ||
} | ||
app.use(nuxt.render) | ||
app.listen(3000) | ||
console.log('Le serveur écoute sur http://localhost:3000') | ||
``` | ||
|
||
Et nous modifions nos scripts dans `package.json` : | ||
|
||
```json | ||
// ... | ||
"scripts": { | ||
"dev": "node server.js", | ||
"build": "nuxt build", | ||
"start": "cross-env NODE_ENV=production node server.js" | ||
} | ||
// ... | ||
``` | ||
|
||
Remarque: vous devrez exécuter `npm install --save-dev cross-env` afin de faire fonctionner l'exemple précédent. Si vous n'êtes pas en train de développer sur Windows, vous pouvez laisser cross-env en dehors de votre script `start` et définir `NODE_ENV` directement. | ||
|
||
## Utilisation du store | ||
|
||
Nous avons besoin d'un état global pour informer notre application si l'utilisateur reste **connecté entre les pages**. | ||
|
||
Pour laisser Nuxt.js utiliser Vuex, nous créons un fichier `store/index.js`: | ||
|
||
```js | ||
import Vue from 'vue' | ||
import Vuex from 'vuex' | ||
|
||
Vue.use(Vuex) | ||
|
||
// Polyfill pour `window.fetch()` | ||
require('whatwg-fetch') | ||
|
||
const store = new Vuex.Store({ | ||
state: () => ({ | ||
authUser: null | ||
}), | ||
|
||
mutations: { | ||
SET_USER(state, user) { | ||
state.authUser = user | ||
} | ||
}, | ||
|
||
actions: { | ||
// ... | ||
} | ||
}) | ||
|
||
export default store | ||
``` | ||
|
||
1. Nous importons `Vue` et `Vuex` (inclus dans Nuxt.js) et nous indiquons à Vue d'utiliser Vuex afin de pouvoir utiliser `$store` dans nos composants. | ||
2. Nous utilisons `require('whatwg-fetch')` afin d'obtenir un polyfill pour la méthode `fetch()` pour tous les navigateurs (consultez le [dépôt fetch](https://github.com/github/fetch)). | ||
3. Nous créons notre mutation `SET_USER` qui va instancier `state.authUser` avec l'utilisateur connecté. | ||
4. Nous exportons notre instance du _store_ vers Nuxt.js afin qu'il puisse l'injecter dans notre application principale. | ||
|
||
### Fonction nuxtServerInit() | ||
|
||
Nuxt.js appellera une action spécifique nommée `nuxtServerInit` avec le contexte comme argument. Ainsi, lorsque l'application sera chargée, le store sera déjà rempli avec certaines données que nous pouvons obtenir du serveur. | ||
|
||
Dans notre `store/index.js`, nous pouvons ajouter l'action `nuxtServerInit` : | ||
|
||
```js | ||
nuxtServerInit ({ commit }, { req }) { | ||
if (req.session && req.session.authUser) { | ||
commit('SET_USER', req.session.authUser) | ||
} | ||
} | ||
``` | ||
|
||
Pour rendre la méthode de données asynchrone, Nuxt.js vous offre différents moyens, choisissez celui avec lequel vous êtes le plus à l'aise : | ||
|
||
1. Retourner une `Promise`, Nuxt.js attendra la résolution de la promesse avant d'afficher le composant. | ||
2. En utilisant [`async` / `await`](https://github.com/lukehoban/ecmascript-asyncawait) ([en savoir plus](https://zeit.co/blog/async-and-await)). | ||
|
||
### L'action login() | ||
|
||
Nous ajoutons une action `login` qui sera appelée à partir de nos composants de pages pour connecter l'utilisateur : | ||
|
||
```js | ||
login ({ commit }, { username, password }) { | ||
return fetch('/api/login', { | ||
// Envoie les cookies client au serveur | ||
credentials: 'same-origin', | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json' | ||
}, | ||
body: JSON.stringify({ | ||
username, | ||
password | ||
}) | ||
}) | ||
.then((res) => { | ||
if (res.status === 401) { | ||
throw new Error('Mauvaise authentification') | ||
} else { | ||
return res.json() | ||
} | ||
}) | ||
.then((authUser) => { | ||
commit('SET_USER', authUser) | ||
}) | ||
} | ||
``` | ||
|
||
### La méthode logout() | ||
|
||
```js | ||
logout ({ commit }) { | ||
return fetch('/api/logout', { | ||
// Envoie les cookies au serveur | ||
credentials: 'same-origin', | ||
method: 'POST' | ||
}) | ||
.then(() => { | ||
commit('SET_USER', null) | ||
}) | ||
} | ||
``` | ||
|
||
## Composants de pages | ||
|
||
Ensuite, nous pouvons utiliser `$store.state.authUser` dans nos composants de pages pour vérifier si l'utilisateur est connecté ou non dans notre application. | ||
|
||
### Rediriger l'utilisateur s'il n'est pas connecté | ||
|
||
Ajoutons une route `/secret` dont le contenu ne peut être vu que par un utilisateur connecté : | ||
|
||
```html | ||
<template> | ||
<div> | ||
<h1>Page super secrète</h1> | ||
<router-link to="/">Retour à l'accueil</router-link> | ||
</div> | ||
</template> | ||
|
||
<script> | ||
export default { | ||
// Nous utilisons`fetch()` car nous n'avons pas besoin d'associer les données à ce composant | ||
fetch({ store, redirect }) { | ||
if (!store.state.authUser) { | ||
return redirect('/') | ||
} | ||
} | ||
} | ||
</script> | ||
``` | ||
|
||
Nous pouvons voir dans la méthode `fetch` que nous appelons `redirect('/')` lorsque notre utilisateur n'est pas connecté. |
Oops, something went wrong.
9616259
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
nuxtjs-with-docus – ./
nuxtjs-with-docus.vercel.app
nuxtjs-with-docus-nuxtlabs.vercel.app
nuxtjs-with-docus-git-dev-nuxtlabs.vercel.app
nuxtjs.docus.com