2014-11-12 15 views
11

Also möchte ich einige Routen in einer API machen, die verschiedene Daten basierend auf der Benutzerrolle, definiert in MongoDB, zeigen. Hier ist eine Auswahl dessen, was ich jetzt habe, es funktioniert ...Überprüfen von Rollen und Authentifizierung mit Passport.js

router.get('/test', passport.authenticate('bearer', {session: false}), function (req, res) { 
    if (req.user.role == "premium") { 
     return res.send('you can see this content'); 
    } 
    else { 
     return res.send('you can not see this content'); 
    } 
}) 

jedoch das Endziel ist mindestens etwas dem Benutzer zu präsentieren, auch wenn sie nicht eingeloggt sind oder authentifiziert mit die richtige Art von Rolle.

router.get('/test', passport.authenticate('bearer', {session: false}), function (req, res) { 
    if (req.user.role == "premium") { 
     return res.send('this is premium content'); 
    } 
    else { 
     // could be hit by another role, or no user at all 
     return res.send([some truncated version of the premium content]); 
    } 
}) 

Was ich denken würde, würde ich herausfinden, wie zu arbeiten, aber ich weiß nicht, wie die gleiche Strecke angeben, die möglicherweise ohne Authorization-Header in der Anfrage getroffen werden könnten.

Ist dies in Passport.js/Express möglich?

+0

Sie werden Ihre eigene Gabel in ordoer das glaube ich – Vinz243

+0

Fork den Paß repo zu ermöglichen, haben zu bauen und das Feature hinzuzufügen, ist das, was Sie meinen? –

+1

Eher dieses, denke ich. Wenn Sie es verwenden. https://github.com/jaredhanson/passport-http-bearer. Die Linien, die Sie betrachten sollten, sind diese https://github.com/jaredhanson/passport-http-bearer/blob/master/lib/strategy.js#L89-101 – Vinz243

Antwort

6

Ich würde vorschlagen, dass Sie verwenden HTTP-Statuscodes und ein Fehlerobjekt, das ist eine gemeinsame Konvention API und es Ihre API ermöglicht es Benutzern, zu wissen, was los ist und warum:

app.get('/premium-resource', function(req, res, next) { 
    passport.authenticate('bearer', function(err, user) { 
    if (user){ 
     if (user.role === 'premium'){ 
     return res.send(200,{userContent:'you are a premium user'}); 
     }else{ 
     return res.send(403,{ 
      'status': 403, 
      'code': 1, // custom code that makes sense for your application 
      'message': 'You are not a premium user', 
      'moreInfo': 'https://myawesomeapi.io/upgrade' 
     }); 
     } 
    }else{ 
     return res.send(401,{ 
     'status': 401, 
     'code': 2, // custom code that makes sense for your application 
     'message': 'You are not authenticated.', 
     'moreInfo': 'https://myawesomeapi.io/docs' 
     }); 
    } 
    })(req, res, next); 
}); 

Disclaimer: ich an Stormpath arbeiten und wir eine Menge Gedanken in API-Authentifizierung und Design setzen, haben wir eine wirklich Präsentation auf der Thema:

https://stormpath.com/blog/designing-rest-json-apis/

+0

Gute Idee! Wer jedoch nicht eingeloggt ist und den Premium-Inhalt in seinem Stream sieht, würde im Grunde einen Fehler in seiner Konsole bekommen, richtig?Ist das eine gute Allgemeinmedizin? Vor allem, wenn eine eckige App auf Fehlercodes wartet und mit anderen Routen/Vorlagen antwortet? –

+0

Ihr Client (eine Angular App, usw.) muss diese Statuscodes oder Fehlermeldungen lesen und entsprechend reagieren - wie Sie es dem Benutzer des Clients zeigen. Das liegt ganz bei Ihnen :) – robertjd

7

Die Lösung besteht darin, den Inhalt in der Ansicht und nicht auf der Route zu beschränken.

router.get('/test', authenticationMiddleware, function(req, res){ 
    var premiumFlag = req.user.role; 
    res.send('premiumontent', {role: premiumFlag}); 
}); 

premiumContent.jade

p This content is visible to all users 

- if role === "premium" 
    p this content is only visible to premium users 
+0

Eine gute Lösung, wenn Sie Jade verwenden, sicher. Was, wenn ich Jade nicht benutze? Ich möchte diese Routen strikt auf einer API halten. –

+1

Wenn Sie eine API erstellen, sollten Sie die Frage so bearbeiten, dass wir API-spezifische Antworten anbieten können. – robertjd

+0

Ist Jade wirklich so weit verbreitet, dass es in einer NodeJS-App implementiert ist? –

1

Die Lösung, die ich auf meine Antwort gefunden habe, ist eine Anpassung der Passportjs.org Dokumentation zu verwenden.

In den Routen Ich muss die Daten zurück, ob ein Benutzer angemeldet ist oder nicht, kann ich so etwas wie verwenden:

// Test to check for authentication 
app.get('/login', function(req, res, next) { 
    passport.authenticate('bearer', function(err, user, info) { 
    if (user) 
     // check user's role for premium or not 
     if (user.role == "premium") 
      return res.send('user is premium') 
     else 
      return res.send('user is not premium'); 
    else 
     // return items even if no authentication is present, instead of 401 response 
      return res.send('not logged in'); 
    })(req, res, next); 
}); 
Verwandte Themen