paspor-lokal dengan node-jwt-simple

87

Bagaimana saya bisa menggabungkan paspor-lokal untuk mengembalikan token JWT pada otentikasi yang berhasil?

Saya ingin menggunakan node-jwt-simple dan melihat passport.js saya tidak yakin bagaimana cara menggunakannya.

var passport = require('passport')
  , LocalStrategy = require('passport-local').Strategy;

passport.use(new LocalStrategy(
  function(username, password, done) {
    User.findOne({ username: username }, function(err, user) {
      if (err) { return done(err); }
      if (!user) {
        return done(null, false, { message: 'Incorrect username.' });
      }
      if (!user.validPassword(password)) {
        return done(null, false, { message: 'Incorrect password.' });
      }
      return done(null, user);
    });
  }
));

Apakah mungkin untuk mengembalikan token saat memanggil done ()? Sesuatu seperti ini ... (hanya kode semu)

if(User.validCredentials(username, password)) {
  var token = jwt.encode({username: username}, tokenSecret);
  done(null, {token : token}); //is this possible?
}

Jika tidak, bagaimana cara mengembalikan token?

cgiacomi.dll
sumber

Jawaban:

123

Saya menemukan jawabannya!

Pertama-tama Anda perlu menerapkan strategi yang benar. Dalam kasus saya, LocalStrategy, dan Anda perlu memberikan logika validasi Anda. Sebagai contoh, mari gunakan yang di paspor-lokal.

var passport = require('passport')
  , LocalStrategy = require('passport-local').Strategy;

passport.use(new LocalStrategy(
  function(username, password, done) {
    User.findOne({ username: username }, function(err, user) {
      if (err) { return done(err); }
      if (!user) {
        return done(null, false, { message: 'Incorrect username.' });
      }
      if (!user.validPassword(password)) {
        return done(null, false, { message: 'Incorrect password.' });
      }
      return done(null, user);
    });
  }
));

verifikasi panggilan kembali yang Anda berikan function(username, password, done)akan mengurus menemukan pengguna Anda dan memeriksa apakah kata sandi cocok (di luar cakupan pertanyaan dan jawaban saya)

passport.js mengharapkan beberapa bagian agar berfungsi, salah satunya adalah Anda mengembalikan pengguna dalam strategi. Saya mencoba mengubah bagian kode itu, dan itu salah. Callback mengharapkan falsejika validasi gagal danobject (pengguna yang divalidasi) jika Anda berhasil.

Sekarang .... bagaimana cara mengintegrasikan JWT?

Dalam rute login Anda, Anda harus menangani autentikasi yang berhasil atau yang tidak berhasil. Dan di sinilah Anda perlu menambahkan pembuatan token JWT. Seperti:

(ingat untuk menonaktifkan sesi, jika tidak Anda harus mengimplementasikan fungsi serialize dan deserialize. Dan Anda tidak memerlukannya jika Anda tidak mempertahankan sesi, yang tidak Anda lakukan jika menggunakan token berbasis auth)

Dari contoh paspor-lokal: (dengan token JWT ditambahkan)

// POST /login
//   This is an alternative implementation that uses a custom callback to
//   achieve the same functionality.
app.post('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) { return next(err) }
    if (!user) {
      return res.json(401, { error: 'message' });
    }

    //user has authenticated correctly thus we create a JWT token 
    var token = jwt.encode({ username: 'somedata'}, tokenSecret);
    res.json({ token : token });

  })(req, res, next);
});

Dan itu dia! Sekarang ketika Anda memanggil / masuk dan POST nama pengguna dan kata sandi (yang harus selalu melalui SSL) potongan kode pertama di atas akan mencoba menemukan pengguna berdasarkan nama pengguna yang Anda berikan dan kemudian memeriksa apakah kata sandi cocok (Tentu saja Anda perlu ubah itu agar sesuai dengan kebutuhan Anda).

Setelah itu, rute masuk Anda akan dipanggil dan di sana Anda dapat menangani pengembalian kesalahan atau token yang valid.

Semoga ini bisa membantu seseorang. Dan jika saya telah membuat kesalahan atau lupa sesuatu beri tahu saya.

cgiacomi.dll
sumber
3
Paspor BasicStrategy atau DigestStrategy dua pilihan lainnya. Tampaknya tidak ada perbedaan besar antara strategi Dasar dan Lokal, karena keduanya tidak memerlukan sesi untuk bekerja - hanya Lokal yang meminta URL pengalihan (membuatnya sedikit kurang ramah API).
funseiki
1
Hai @cgiacomi, bisakah Anda memberikan contoh rute yang memeriksa token?
Matt Kim
3
Hei @ matt-kim sebenarnya saya tidak menyimpan tokennya, itu sementara. Saya tidak tahu apakah ini cara terbaik atau tidak, tetapi inilah yang saya lakukan: Pengguna mengautentikasi, dan saya membuat token dan mengembalikannya ke klien. Token disimpan di localStorage jika klien adalah situs web, atau Anda dapat menyimpannya di aplikasi iPhone / Android. Ketika klien harus membuat permintaan untuk sumber daya, ia mengirimkan token yang disimpan ke backend. Paspor akan menangani token tersebut. Berikut adalah inti dari strategi Bearer untuk menangani token gist.github.com/cgiacomi/cd1efa187b8cccbe2a61 Semoga ini bisa membantu! :)
cgiacomi
1
Hai @cgiomi! mungkin sudah jelas, tetapi dapatkah Anda menjelaskan cara menonaktifkan sesi saat menggunakan callback kustom?
MrMuh
2
@MrMuh periksa tautan gist.github.com/cgiacomi/cd1efa187b8cccbe2a61 di komentar saya, saya tunjukkan cara menonaktifkan sesi: passport.authenticate ('bearer', {session: false})
cgiacomi
18

Ini adalah solusi yang bagus, saya hanya ingin menambahkan ini:

var expressJwt = require('express-jwt');

app.use('/api', expressJwt({secret: secret}));

Saya suka menggunakan "express-jwt" untuk memvalidasi token.

btw: artikel ini sangat bagus untuk mempelajari cara menangani token di sisi klien, menggunakan Angular, untuk mengirimkannya kembali dengan setiap permintaan

https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/

ZeroCR
sumber
2
Saya hanya biasa express-jwtmelakukan otentikasi, tetapi membaca dokumentasi paket lain seperti passport-jwt, saya pikir saya akan tetap menggunakannya express-jwt. Jauh lebih sederhana, IMO jauh lebih baik
bobbyz
Just an FYI express-jwt tidak memberikan dukungan untuk token penyegaran.
pengguna3344977