For example /graphql should only be accessed by logged in user.
PS: Sorry if there were similar questions that's resolved, please reference me then. Thanks!
You can use middlewares.
Server-side pseudo-code:
app.use('/graphql',
+(req, res, next) => {
+ if (!req.user) { // if user is not logged in
+ res.status(400);
+ res.send('Access denied');
+ } else {
+ next();
+ }
+},
expressGraphQL(req => ({
schema,
graphiql: true,
rootValue: { request: req },
pretty: process.env.NODE_ENV !== 'production',
})));
but I think it would be better take a look on src/data/queries/me.js:
const me = {
...
resolve({ request }) {
return request.user && { // return user only if we are logged in
... // some result
};
},
};
If you need to protect frontend route, you can check out src/routes/admin/index.js:
async action() {
if (!isAdmin) { // Redirect to login page if user is not admin
return { redirect: '/login' };
}
...
},
in case if i want to protect more than one route, lets say 10 routes, then in each route i have to check the condition and then redirect the page.
Is their another way to handle such situation, so that i don't have to define redirect route every time. is it possible to define a wrapper class or service which will check the given condition and if condition satisfies, then allow that route to hit otherwise redirect to login route or some other route
@gauravprwl14 UniversalRouter also has middleware support, for example:
const adminRoutes = {
path: '/admin',
children: [
{ path: '/', action() { return 'Admin Page' } },
{ path: '/users', action() { return 'Users' } },
{ path: '/posts', action() { return 'Posts' } },
],
async action({ store, next }) {
// Redirect to login page if user is not admin
if (!store.getState().isAdmin) {
return { redirect: '/login' };
}
// or display proper chid page, eg /admin/users
return await next();
},
};
thanks for the help i try to implement it.
But when i tried to refresh the page, its alway redirect me to login page as on refresh my store is empty. i have used redux persist to persist the store but this didn't work out. can you suggest some work around, to resolve this problem.
@gauravprwl14 just fill the store on server-side with necessary data:
/* server.js */
store: createStore({
isAdmin: req.user ? req.user.role === 'admin' : false,
}),
See #883 for more info
@frenzzy how do you add user data in request?
Hi @frenzzy suppose my user has already authenticated locally. He then refreshes the page. My server pick up the request but must have a way to identify this user who has already logged in before. So does it mean I need store token-like cookies such that my server can identify the user from the cookies?
@tzyhhaur Passport.JS already does this job for you.
When user logging in using credentials (or facebook), passport.js saves user information (1, 2) in cookies. It uses signed JWT to verify that information wasn't edited by user.
Later, after page refresh, it reads this JWT token from cookie id_token and populates req.user property with user id and email if JWT token was valid.
Hi @maksimkurb thank you for the reply. Is the passport.js file only applicable to Facebook login? If I were to use other authentication platform like Firebase, I would have to rewrite the passport.js file, right?
@tzyhhaur you can think about PassportJS as about abstraction layer of your authentication with pluggable auth strategies for various services. You can install one of them (e.g. facebook, google-oauth, yahoo, paypal) and write your own callback (to register user if it is not registered yet for ex.) which just should return some basic user information (like id and email in /src/core/passport.js), so later you can use it by req.user on your callbacks.
There is strategy for firebase, so you can implement it (in /src/core/passport.js and /src/server.js files) like facebook implemented in this boilerplate.
Thank you very much @maksimkurb That clears up a lot!
Most helpful comment
You can use middlewares.
Server-side pseudo-code:
but I think it would be better take a look on
src/data/queries/me.js:If you need to protect frontend route, you can check out
src/routes/admin/index.js: