Feathers: Tambahkan dukungan untuk token penyegaran

Dibuat pada 22 Des 2015  ·  64Komentar  ·  Sumber: feathersjs/feathers

Saat ini kami mengizinkan mendapatkan token baru dengan memposting token autentikasi yang valid ke <loginEndpoint>/refresh . Refresh token memiliki alur kerja yang sedikit berbeda seperti yang dijelaskan di sini:
https://auth0.com/learn/refresh-tokens

Authentication Feature

Komentar yang paling membantu

Fitur ini HARUS ketika datang ke aplikasi React Native. Pengguna masuk di awal dan ketika dia membuka aplikasi setelah beberapa minggu, dia berharap untuk tetap masuk.

Semua 64 komentar

:+1: @corymsmith dan saya membicarakan hal ini. Berharap untuk membantu menendang beberapa dari ini melewati garis finish selama "liburan".

Kami memiliki dukungan untuk ini di master tetapi juga memiliki dukungan untuk ini di cabang decoupling . Untuk menyegarkan token, Anda memiliki 2 opsi:

  1. Anda dapat mengautentikasi ulang menggunakan email/kata sandi, twitter, dll.
  2. Anda dapat memberikan token yang valid ke GET /auth/token/refresh

Kami memiliki proses pembaruan token, tetapi tidak sepenuhnya mendukung token penyegaran seperti yang dijelaskan dalam tautan Auth0 yang saya posting di atas. Token penyegaran yang sebenarnya berfungsi mirip dengan kode/kata sandi autentikasi GitHub, tetapi hanya dapat digunakan untuk mendapatkan token JWT baru. Jadi meskipun token JWT Anda kedaluwarsa, jika Anda memiliki token penyegaran, Anda dapat menggunakannya untuk masuk lagi. Mereka bertahan ke database dengan userId utuh dan dapat dicabut kapan saja. Setidaknya, itulah yang saya kumpulkan dari artikel Auth0.

Ah kamu benar @marshallswain. Sepertinya saya harus mengklik tautannya :wink:

Saya pikir untuk potongan pertama kita akan meninggalkan ini dari tonggak 1,0 kemudian. Cukup mudah bagi orang untuk mengautentikasi ulang.

Saya agak memilih bahwa kami membuat ini feathers-authentication 2.0 hal.

Pikiran yang hebat.

Saya masih cukup bingung karena tidak jelas bagaimana tepatnya alur kerja otentikasi bekerja.

Apa yang saya lakukan saat ini adalah.
1.) Klien mengirim nama pengguna & kata sandi

 curl -X POST https://xxx/auth/local   -H "Content-Type: application/json"   -d '{ "email":"xxx", "password":"yyy"}'

Ini mengembalikan token JWT.

{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJfaWQiOiI1NzhhNjUyN2RkMTZiMjIwMDRhY2ZjNmEiLCJpYXQiOjE0NzAzMjYyODUsImV4cCI6MTQ3MDQxMjY4NSwiaXNzIjoiZmVhdGhlcnMifQ.OVvQbnxfoDGxPFm3Y6tBhRae2Qa6_mDq-PVIo8RcC8Y"}

2.) Kemudian, saya meletakkan token ini di header http Authorizatin untuk mengakses API.

curl -X GET https://xxx/users  -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJfaWQiOiI1NzhhNjUyN2RkMTZiMjIwMDRhY2ZjNmEiLCJpYXQiOjE0NzAzMjU1NzYsImV4cCI6MTQ3MDQxMTk3NiwiaXNzIjoiZmVhdGhlcnMifQ._CHdx3RpEuI189t90mXq-IMPXRNuoVh7nBwY1ON7xCY'

Hal yang saya tidak mengerti selanjutnya adalah bagaimana sebenarnya me-refresh token ini.
Apa yang saya coba adalah saya mengirim token ini ke xxx/auth/token/refresh
Apa yang saya dapatkan hanyalah token yang sangat panjang. Saya kemudian mencoba menggunakan token lama dan baru ini untuk mengakses API. keduanya berfungsi ... (bukankah yang lama harus dinonaktifkan?)

curl -X GET https://xxx/auth/token/refresh  -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJfaWQiOiI1NzhhNjUyN2RkMTZiMjIwMDRhY2ZjNmEiLCJpYXQiOjE0NzAzMjU1NzYsImV4cCI6MTQ3MDQxMTk3NiwiaXNzIjoiZmVhdGhlcnMifQ._CHdx3RpEuI189t90mXq-IMPXRNuoVh7nBwY1ON7xCY'
{"query":{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJfaWQiOiI1NzhhNjUyN2RkMTZiMjIwMDRhY2ZjNmEiLCJpYXQiOjE0NzAzMjU1NzYsImV4cCI6MTQ3MDQxMTk3NiwiaXNzIjoiZmVhdGhlcnMifQ._CHdx3RpEuI189t90mXq-IMPXRNuoVh7nBwY1ON7xCY"},"provider":"rest","token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJxdWVyeSI6eyJ0b2tlbiI6ImV5SjBlWEFpT2lKS1YxUWlMQ0poYkdjaU9pSklVekkxTmlKOS5leUpmYVdRaU9pSTFOemhoTmpVeU4yUmtNVFppTWpJd01EUmhZMlpqTm1FaUxDSnBZWFFpT2pFME56QXpNalUxTnpZc0ltVjRjQ0k2TVRRM01EUXhNVGszTml3aWFYTnpJam9pWm1WaGRHaGxjbk1pZlEuX0NIZHgzUnBFdUkxODl0OTBtWHEtSU1QWFJOdW9WaDduQndZMU9ON3hDWSJ9LCJwcm92aWRlciI6InJlc3QiLCJ0b2tlbiI6ImV5SjBlWEFpT2lKS1YxUWlMQ0poYkdjaU9pSklVekkxTmlKOS5leUpmYVdRaU9pSTFOemhoTmpVeU4yUmtNVFppTWpJd01EUmhZMlpqTm1FaUxDSnBZWFFpT2pFME56QXpNalUxTnpZc0ltVjRjQ0k2TVRRM01EUXhNVGszTml3aWFYTnpJam9pWm1WaGRHaGxjbk1pZlEuX0NIZHgzUnBFdUkxODl0OTBtWHEtSU1QWFJOdW9WaDduQndZMU9ON3hDWSIsImRhdGEiOnsiX2lkIjoiNTc4YTY1MjdkZDE2YjIyMDA0YWNmYzZhIiwiaWF0IjoxNDcwMzI1NTc2LCJleHAiOjE0NzA0MTE5NzYsImlzcyI6ImZlYXRoZXJzIiwidG9rZW4iOiJleUowZVhBaU9pSktWMVFpTENKaGJHY2lPaUpJVXpJMU5pSjkuZXlKZmFXUWlPaUkxTnpoaE5qVXlOMlJrTVRaaU1qSXdNRFJoWTJaak5tRWlMQ0pwWVhRaU9qRTBOekF6TWpVMU56WXNJbVY0Y0NJNk1UUTNNRFF4TVRrM05pd2lhWE56SWpvaVptVmhkR2hsY25NaWZRLl9DSGR4M1JwRXVJMTg5dDkwbVhxLUlNUFhSTnVvVmg3bkJ3WTFPTjd4Q1kifSwiaWF0IjoxNDcwMzI2NDQyLCJleHAiOjE0NzA0MTI4NDIsImlzcyI6ImZlYXRoZXJzIn0.TqUv3051TTGbX4cPfkN-6pOOB5SN9nH-E7TU1HHSsb8","data":{"_id":"578a6527dd16b22004acfc6a","iat":1470325576,"exp":1470411976,"iss":"feathers","token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJfaWQiOiI1NzhhNjUyN2RkMTZiMjIwMDRhY2ZjNmEiLCJpYXQiOjE0NzAzMjU1NzYsImV4cCI6MTQ3MDQxMTk3NiwiaXNzIjoiZmVhdGhlcnMifQ._CHdx3RpEuI189t90mXq-IMPXRNuoVh7nBwY1ON7xCY"}}

Yang lebih aneh lagi adalah saya mencoba menggunakan token baru ini dan mengirim ke /auth/token/refresh lagi.
Saya mendapat token yang lebih panjang dari yang ini.

Saya tidak yakin apa yang saya lakukan salah atau salah paham di sini. Silakan menyarankan.

@parnurzeal kami belum memiliki dukungan token penyegaran. Itu sebabnya ini adalah fitur yang diusulkan.

Cara mendapatkan token baru adalah dengan melakukan POST ke /auth/token dengan JWT valid yang ada atau login menggunakan mekanisme auth lain. Sepertinya Anda melakukan semuanya dengan benar.

Benar, tapi tolong perhatikan baik-baik bagaimana saya melakukannya dan hasil yang saya dapatkan.

Mari kita gunakan contoh yang mudah.
Ketika saya meminta token baru menggunakan abcdefghijklmno (hanya token omong kosong acak).
Respons balik hanyalah versi yang lebih panjang dari token sebelumnya -> abcdefghijklmnopqrstuvwxyz
Jika saya mencoba melakukannya lagi menggunakan abcdefghijklmnopqrstuvwxyz , saya akan mendapatkan versi yang lebih panjang ->
abcdefghijklmnopqrstuvwxyz1234567890 dan loop berlangsung (meminta lebih banyak Anda mendapatkan versi yang lebih panjang dari yang sebelumnya).

Juga, ketiga token di atas semuanya dapat digunakan secara bersamaan.
Bukankah seharusnya token sebelumnya menjadi kedaluwarsa setelah kami meminta token baru?

@parnurzeal yang saya katakan adalah jangan lakukan apa yang Anda lakukan karena fitur itu tidak benar-benar diimplementasikan. Berdasarkan implementasi (sejauh ini) fakta bahwa token terus bertambah setiap kali Anda menekan /auth/token/refresh adalah karena kami hanya memasukkan data kembali ke token. Ini bukan cara kerjanya dan kami tidak punya waktu untuk menyelesaikannya dan mengapa ini tidak didokumentasikan. Anda tidak seharusnya menggunakannya.

Bukankah seharusnya token sebelumnya menjadi kedaluwarsa setelah kami meminta token baru?

Ini adalah sifat dari JWT. Mereka kedaluwarsa sendiri dari TTL mereka. Jika Anda ingin mencegah token lama digunakan yang belum kedaluwarsa, maka Anda perlu mempertahankan daftar hitam. Saat ini, ini terserah Anda dan kami memiliki masalah terbuka (#133) seputar itu tetapi kemungkinan tidak akan segera mencapainya (jika pernah).

Hai, saya melihat /auth/refresh/token dan saya keluar dengan sesuatu seperti itu:

...
function pick (o, ...props) {
  return Object.assign({}, ...props.map(prop => ({[prop]: o[prop]})));
}

// Provider specific config
const defaults = {
  payload: ['id', 'role'],
  passwordField: 'password',
  issuer: 'feathers',
  algorithm: 'HS256',
  expiresIn: '1d', // 1 day
};
...
// GET /auth/token/refresh
  get (id, params) {
    if (id !== 'refresh') {
      return Promise.reject(new errors.NotFound());
    }

    const options = this.options;

    // Add payload fields
    const data = pick(params.payload, options.payload);

    return new Promise(resolve => {
      jwt.sign(data, config.get('auth').token.secret, options, token => {
        return resolve({token: token});
      });
    });

  }

Apakah itu terlalu naif sebagai implementasi? Jika tidak, saya dapat mencoba memoles, menambahkan beberapa tes dan membuat PR.

@aboutlo terima kasih atas usahanya! Yang terbaik adalah menunggu sampai v0.8 keluar (sudah dalam versi alfa untuk sementara waktu sekarang) karena ada banyak perubahan yang telah terjadi dan rute itu mungkin akan dihentikan minggu ini.
Saya memotong rilis beta hari ini dan saat ini menyelesaikan panduan migrasi. Jadi itu tidak akan lama dan v0.8 membahas banyak masalah saat ini dengan auth.

Kami telah memberikan banyak pemikiran untuk menyegarkan token sehingga setelah 0.8 dirilis (minggu ini) saya ingin membahas masalah ini. Saya mungkin akan mengajukan pemikiran awal kami akhir pekan ini.

cukup adil @ekryski , saya akan menunggu 0.8 :)

Fitur ini HARUS ketika datang ke aplikasi React Native. Pengguna masuk di awal dan ketika dia membuka aplikasi setelah beberapa minggu, dia berharap untuk tetap masuk.

@deiucanta kabar baiknya adalah kami terus mengingat fitur ini saat kami merancang [email protected]. Saya tidak berpikir itu akan lama sebelum kita mendapatkannya dan didokumentasikan.

itu kabar baik! 👍 ditunggu ya

@marshallswain Menantikan pembaruan fitur ini. Tolong beri tahu saya kapan kita bisa mengharapkan ini. Atau sudah rilis? Terima kasih sebelumnya.

@deiucanta Sementara itu, hingga fitur ini dirilis, Anda dapat menggunakan token yang berumur lebih panjang. Setelah dirilis, Anda dapat merotasi rahasia autentikasi Anda ke nilai baru untuk menghapus semua sesi yang ada, dan membuat semua pengguna Anda mengikuti sesi yang lebih pendek dan diperbarui.

@atulrpandey itu tidak dirilis secara resmi tetapi tidak sulit untuk diterapkan juga. Anda cukup menambahkan kait untuk menghasilkan token penyegaran baru dan menyimpannya di objek pengguna di DB dan setelah digunakan atau kedaluwarsa, Anda menghapusnya dari pengguna.

@petermikitsh hal lain yang dapat Anda lakukan (jika Anda menggunakan ponsel) adalah menyimpan clientId dan clientSecret dengan aman di klien dan jika JWT accessToken kedaluwarsa, Anda cukup mengautentikasi ulang dengan itu.

@ekryski dapatkah Anda memberikan contoh salah satu dari strategi ini? itu akan sangat membantu.
atau, apakah perlu waktu lama untuk merilis dukungan resmi? ini akan sangat membantu dengan autentikasi seluler!

Tentang topik token penyegaran:

Token penyegaran membawa informasi yang diperlukan untuk mendapatkan token akses baru. Dengan kata lain, setiap kali token akses diperlukan untuk mengakses sumber daya tertentu, klien dapat menggunakan token penyegaran untuk mendapatkan token akses baru yang dikeluarkan oleh server otentikasi. Kasus penggunaan umum termasuk mendapatkan token akses baru setelah yang lama kedaluwarsa, atau mendapatkan akses ke sumber daya baru untuk pertama kalinya. Token penyegaran juga dapat kedaluwarsa tetapi berumur panjang. Token penyegaran biasanya tunduk pada persyaratan penyimpanan yang ketat untuk memastikan mereka tidak bocor. Mereka juga dapat masuk daftar hitam oleh server otorisasi. - https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/

Jadi saya masuk ke React Native sendiri lebih cepat dari yang saya kira. Saya berpikir untuk mungkin berkontribusi ini, tetapi saya ingin memastikan bahwa saya sepenuhnya memahami mekanisme untuk memastikan itu adalah implementasi yang benar. Karena token penyegaran bukan tanpa kewarganegaraan, akan ada beberapa kendala dalam penggunaan (misalnya, pengembang perlu menyediakan adaptor penyimpanan).

Bisakah Anda menggunakan JWT yang valid untuk mendapatkan token penyegaran? Atau apakah token penyegaran secara otomatis dikembalikan dalam respons autentikasi (mis., selain accessToken )? Sepertinya Auth0 menyertakan mereka dalam tanggapan otentikasi (baik accessToken dan refreshToken ) dalam contoh mereka di https://auth0.com/learn/refresh-tokens/.

@petermikitsh Saya tidak berpikir Anda harus dapat menggunakan JWT yang valid untuk mendapatkan token penyegaran. Jika Anda melakukannya, siapa pun bisa mendapatkan JWT dan tetap mengakses akun.

Token Penyegaran biasanya dikembalikan dengan respons masuk/pendaftaran dan kemudian klien tidak dapat benar-benar mendapatkan akses ke sana lagi untuk sesi tertentu kecuali mereka masuk/mendaftar lagi yang memberi mereka sesi baru dan token penyegaran baru.

Refresh Token tidak benar-benar perlu kedaluwarsa tetapi mereka dapat dibangkitkan jika disimpan dalam database dan dengan cara ini, pengguna juga dapat melihat berapa banyak sesi aktif yang mereka miliki. Anda dapat menyimpan lebih banyak info saat mengeluarkan token penyegaran (seperti os, ip, nama perangkat, dll. agar dapat dikenali - seperti yang dilakukan Facebook, GitHub).

Setidaknya begitulah cara saya melakukannya.

Seharusnya boleh menggunakan JWT yang valid untuk mendapatkan token penyegaran selama Anda memeriksa otorisasi saat Anda mengeluarkan token penyegaran dan ketika Anda mencoba menggunakan token penyegaran.

@marshallswain

Saat ini kami mengizinkan mendapatkan token baru dengan memposting token autentikasi yang valid ke <loginEndpoint>/refresh . Segarkan token memiliki alur kerja yang sedikit berbeda ...

Jadi itu harus disebut renew bukan refresh untuk menghindari kebingungan <loginEndpoint>/renew

Seperti yang dikatakan @abhishekbhardwaj

accessToken, tidak boleh di-refresh oleh accessToken, tetapi hanya dengan refresehToken atau nama pengguna/kata sandi, refreshToken hanya boleh disegarkan oleh otentikasi pengguna/kata sandi, atau rahasia lain, yang tidak dapat diakses oleh browser, seperti 2 faktor autentik...

Saat ini, dimungkinkan untuk menyegarkan accessToken Anda dengan accessToken, seperti yang disebutkan di sini:

https://github.com/feathersjs/authentication-jwt/issues/61

Pendekatan lain adalah menyimpan token penyegaran di dalam muatan accessToken, lalu api penyegaran saat ini memeriksa apakah token penyegaran tidak dicabut (melalui basis data atau panggilan redis). Dengan cara ini, token penyegaran bisa menjadi id kenaikan otomatis sederhana. Juga menyegarkan api seharusnya tidak memeriksa kedaluwarsa lagi. Karena token penyegaran (bilangan bulat sederhana) ditandatangani dengan token akses, itu aman.

Cara ini mengubah basis kode saat ini harus minimal: Untuk api penyegaran berikan cara agar pengguna dapat memberikan pengait untuk memeriksa apakah token akses tidak dicabut (melalui pemeriksaan token penyegaran di dalam muatannya), jika pengait ini disediakan jangan' t memvalidasi waktu kedaluwarsa lagi.

Bisakah Anda menjelaskan pendekatan ini lagi @ arash16 ?

Jika Anda menyimpan token penyegaran di payload accessTokens, dan API penyegaran tidak memeriksa kedaluwarsa, bukankah Anda baru saja secara efektif membuat setiap accessToken "tidak kedaluwarsa"

Karena accessToken apa pun bisa digunakan untuk mendapatkan token akses baru, bukan?

Apakah saya melewatkan sesuatu?

@BigAB
Maksud saya jangan periksa kedaluwarsa hanya untuk refresh api , accessToken yang sama digunakan sebagai token penyegaran dan token akses. Token ini tidak kedaluwarsa hanya untuk menyegarkan dan mendapatkan token akses baru, id penyegaran itu sendiri dapat dicabut oleh pengguna secara manual .

Pengembang harus memiliki tabel-db/redis untuk menyimpan semua id penyegaran. Ketika pengguna perlu mencabut atau keluar dari beberapa (atau semua) sesi lain, kami dapat memberinya daftar semua id penyegaran (ditambah beberapa info tambahan lainnya seperti browser atau tanggal pembuatan dll) dan dia memilih untuk menghapus (menandatangani -keluar dari) mereka secara selektif. Setelah itu setelah token aktual yang berisi id penyegaran tersebut kedaluwarsa, api penyegaran menolak untuk memberikan yang baru.

Token dalam id penyegaran tidak digunakan sebagian besar waktu dan otorisasi tidak memiliki kewarganegaraan sampai token kedaluwarsa, setelah itu kami mungkin memiliki satu panggilan ke db untuk memvalidasi id penyegaran dan mengembalikan token akses baru.

Waktu kedaluwarsa token akses bisa pendek (kurang dari 10 menit), pengguna dapat menutup halaman dan pergi, kemudian ketika dia membuka halaman, token akses sudah kedaluwarsa dan dia logout. Tetapi refresh-id di dalam token memiliki time-to-live yang jauh

Dari sudut pandang keamanan, token akses yang digunakan dengan cara ini harus diperlakukan seperti kunci sesi lama, dengan manfaat tambahan bahwa kita tidak perlu memanggil database untuk memvalidasinya setiap kali (hanya sekali kedaluwarsa).

@arash16 , saya suka ide Anda untuk menyimpan token penyegaran di dalam akses JWT. Apakah ada contoh, bagaimana cara mengambil token penyegaran ini di sisi server?

Masalah saya saat ini: Jika token akses kedaluwarsa, muatan tidak tersedia dalam konteks kait bulu. Saya kira, caranya adalah dengan menggunakan fungsi utilitas verifyJWT() dari paket @feathersjs/authentication , misalnya di awal app.service('authentication').hooks({ before: { create: ... } }) ?

Apakah ada cara yang bijaksana untuk menggunakan token penyegaran di bulu sekarang? Adakah rencana untuk menambahkan dukungan untuk mereka?

Halo semua ,

Sepertinya masih belum tersedia (atau apakah saya melewatkan sesuatu). Bisakah Anda memberi tahu kami kapan itu akan tersedia? Saya melihat ada repositori token penyegaran paspor yang tersedia. Ada yang mencoba ini?
https://github.com/fiznool/passport-oauth2-refresh

Halo @daffl ,
Adakah yang bisa membantu saya memahami bagaimana token dapat disegarkan untuk strategi google? Karena saya tidak akan memiliki kata sandi untuk skenario login google?

Terima kasih

Pendekatan lain adalah menyimpan token penyegaran di dalam muatan accessToken

Jadi siapa pun yang bahkan memiliki kedaluwarsa akan dapat dengan mudah menghasilkan jumlah token akses baru yang tak ada habisnya atau apakah saya melewatkan sesuatu?

Token penyegaran harus disimpan dengan aman di klien dan tidak seorang pun kecuali klien ini yang boleh mengaksesnya!

@deiucanta kabar baiknya adalah kami terus mengingat fitur ini saat kami merancang [email protected]. Saya tidak berpikir itu akan lama sebelum kita mendapatkannya dan didokumentasikan.

Ini diposting di 2016. Guys, apakah Anda masih memiliki rencana untuk mendukung fitur yang harus dimiliki ini?

Tidak. Anda tidak dapat melakukan apa pun dengan token yang kedaluwarsa. Selain itu, token penyegaran jauh lebih mudah dilakukan di prarilis v4 . Entri buku masak tentang cara melakukannya akan menjadi bagian dari rilis final.

Selain itu, token penyegaran jauh lebih mudah dilakukan di prarilis v4 .

Apakah ada perkiraan tanggal rilis?

Entri buku masak tentang cara melakukannya akan menjadi bagian dari rilis final.

Sampai panduan ini dirilis, dapatkah Anda menjelaskan dalam beberapa kata bagaimana hal itu dapat dilakukan di prarilis v4?

@daffl ping

Apakah ada cara resmi untuk melakukan ini? v4 ada di sini dan saya tidak melihat apa pun di dokumen

@daffl dapatkah Anda menguraikan bagaimana ini dapat dicapai dengan 4.0 dan tanpa peretasan ke layanan otentikasi?

@MichaelErmer sebagai solusi Anda dapat menggunakan lokal atau strategi khusus apa pun untuk memperbarui jwt, tidak ideal, tetapi berfungsi dengan baik untuk komunikasi internal, katakanlah antara pekerja dan api.

function initAuth() {
  return async (ctx) => {
    if (ctx.path !== 'authentication') {
      const [authenticated, accessToken] = await Promise.all([
        ctx.app.get('authentication'),
        ctx.app.authentication.getAccessToken(),
      ]);

      if (!accessToken || !authenticated) {
        const result = await ctx.app.authenticate(apiLocalCreds);
        ctx.params = {
          ...ctx.params,
          ...result,
          headers: { ...(ctx.params.headers || {}), Authorization: result.accessToken },
        };
      } else {
        const { exp } = decode(accessToken);
        const expired = Date.now() / 1000 > exp - 60 * 60;
        if (expired) {
          const result = await ctx.app.authenticate(apiLocalCreds);
          ctx.params = {
            ...ctx.params,
            ...result,
            headers: { ...(ctx.params.headers || {}), Authorization: result.accessToken },
          };
        }
      }
    }
    return ctx;
  };
}

client
  .configure(rest(apiHost).superagent(superagent))
  .configure(auth(authConfig))
  .hooks({ before: [initAuth()] });

Saat ini saya menggunakan kait after di v4 authentication , untuk memperbarui accessToken saya setelah 20 hari...

````javascript
const {DateTime} = membutuhkan('luxon')
const renewAfter = {hari: 20}

modul.ekspor = () => {
kembalikan konteks asinkron => {
jika (
konteks.metode === 'buat' &&
context.type === 'setelah' &&
context.path === 'otentikasi' &&
konteks.data && konteks.data.strategi === 'jwt' &&
konteks.hasil &&
context.result.accessToken) {
// periksa apakah token perlu diperbarui
const payload = menunggu context.app.service('authentication').verifyAccessToken(context.result.accessToken)
const dikeluarkanAt = DateTime.fromMillis(payload.iat * 1000)
const perbaruiSetelah = dikeluarkanAt.plus(perbaruiSetelah)
const sekarang = DateTime.local()
if (sekarang > perbaruiSetelah) {
context.result.accessToken = menunggu context.app.service('authentication').createAccessToken({sub: payload.sub})
}
}
kembali konteks
}
}
````

Sangat penting untuk memiliki kait ini di after dan sebagai kait terakhir, sehingga semua verifikasi dll telah berlalu

Adakah rencana untuk mengintegrasikan token penyegaran di bulu?

Saya kedua pertanyaan itu satu pesan sebelumnya.

Saya juga bertanya-tanya tentang alur kerja token penyegaran. Apakah solusi yang dibuat oleh @m0dch3n merupakan praktik yang baik? Haruskah kita menerapkannya dengan cara lain?

Seluruh alur kerja refreshToken menurut pendapat saya hanya melindungi sedikit saja dari serangan man in the middle, sehingga jika middle man mencuri accessToken dia setidaknya tidak bisa me-refresh dan memiliki akses tak terbatas ke sumber daya.

Itu tidak melindungi terhadap XSS, karena dalam kasus itu, penyerang dapat mencuri apa pun yang disimpan di sisi klien. Begitu juga refreshToken...

Masalahnya sekarang adalah, jika Anda membuat waktu kedaluwarsa accessToken Anda terlalu kecil (yaitu 5 menit), Anda juga harus lebih sering me-refresh. Pria di tengah hanya perlu mendengarkan permintaan klien selama 5 menit untuk mencegat refreshToken lalu... Jika Anda membuat masa berlakunya lebih lama, ia memiliki akses yang lebih lama hanya dengan accessToken...

Sejujurnya jika beberapa klien memberi tahu saya, aksesnya dicuri, saya tetap harus memasukkan accessToken DAN refreshToken untuk memastikannya. Jadi saya terpaksa membuat permintaan DB pada setiap permintaan.

Dalam kasus saya, ketika saya mengetahui kasus seperti itu, saya blacklist semua accessTokens dari 40 hari terakhir, karena accessTokens saya memiliki validitas 40 hari...

Menggunakan permintaan HTTPS membuat serangan man in the middle menjadi sangat sulit. Apakah Anda tidak menggunakan permintaan HTTPS?

Tentu saja saya menggunakan https, tetapi ada 3 kemungkinan untuk mencuri accessToken. Pertama di sisi klien (yaitu XSS), kedua di transportasi (manusia di tengah), dan ketiga di sisi server.

Pada klien dan transportasi, saya hanya bertanggung jawab setengah untuk keamanan, dan setengah lainnya adalah klien, yang tidak sepenuhnya di bawah kendali saya. Tetapi saya dapat membantu klien, untuk menghindari risiko keamanan, dengan membuat XSS menjadi tidak mungkin dan dengan mengamankan transportasi dengan https...

Tujuan dari refreshToken adalah, untuk mempersingkat masa berlaku accessToken DAN untuk tidak mengirimkan token valid yang lebih lama atau tidak terbatas pada SETIAP permintaan

Jadi satu-satunya keamanan yang dibawanya, adalah dari 100 permintaan yaitu, Anda tidak membuat semua 100 rentan pada transportasi, tetapi hanya 1 permintaan

Jadi pada dasarnya seorang pria di tengah serangan, tidak dapat dilindungi oleh refeshToken dan tentu saja tidak oleh XSS... Itu hanya dapat dikurangi, dengan berapa kali Anda mengirimkan refreshToken ini... Biaya transmisinya lebih rendah namun, accessToken harus lebih valid...

Saya baru saja menyalin/melewati komentar saya dari saluran Slack:

Saya pikir token penyegaran adalah fitur yang harus didukung dan ini bukan tentang memperbarui token akses yang ada secara otomatis. Token akses tidak memiliki kewarganegaraan dan tidak akan disimpan di sisi server. Sisi bawahnya adalah berlaku selamanya! Semakin lama token akses, semakin banyak risiko yang dikenakan. Tetapi jika token akses terlalu pendek, maka pengguna Anda harus sering login, itu akan sangat mempengaruhi kegunaan.

Di situlah token penyegaran masuk, token yang digunakan untuk menyegarkan token akses dan itu adalah token yang berumur panjang. Ketika token akses kedaluwarsa, klien dapat menggunakan token penyegaran untuk mendapatkan token akses baru, dan itulah satu-satunya tujuan token penyegaran.

Token penyegaran dapat dicabut jika akun pengguna telah disusupi. Dan itulah perbedaan besar antara token akses dan token penyegaran. Untuk mencabut token penyegaran yang dikeluarkan, server harus menyimpan semua token penyegaran yang dikeluarkan. Dengan kata lain, token penyegaran adalah stateful. Server perlu tahu mana yang valid mana yang tidak valid.

Untuk mengimplementasikan token penyegaran dengan benar, kita memerlukan semacam penyimpanan token untuk mempertahankan token penyegaran. Kita juga perlu menerapkan setidaknya tiga aliran:

Segarkan validasi token
Segarkan token akses dengan token penyegaran yang valid
Cabut token penyegaran pengguna yang disusupi

Ada fungsi manajemen lain yang juga bagus untuk dimiliki seperti statistik penggunaan token.

Di atas adalah pemahaman saya saat ini tentang cara menerapkan token penyegaran. Hal ini tidak mudah tetapi pasti diperlukan untuk membangun sistem yang lebih aman.

Ternyata Feathers sudah memiliki semua fungsi/modul yang diperlukan untuk mengimplementasikan token penyegaran dengan benar:

  1. Toko token penyegaran: dapat dengan mudah didukung oleh Layanan Bulu.
  2. Menerbitkan dan memvalidasi token penyegaran: hanya dapat menggunakan kembali dukungan JWT yang ada yang memiliki AuthenticationService.

Berdasarkan pekerjaan yang dilakukan oleh TheSinding (https://github.com/TheSinding/authentication-refresh-token), saya menerapkan token penyegaran versi saya sendiri dengan satu layanan khusus dan tiga kait (https://github.com/ jackywxd/feathers-refresh-token) yang memungkinkan fungsionalitas token penyegaran dasar:

  1. Keluarkan token penyegaran setelah otentikasi pengguna berhasil;
  2. Segarkan token akses dengan token penyegaran JWT yang valid;
  3. Logout pengguna dengan menghapus token penyegaran

Meskipun sepenuhnya memanfaatkan basis kode yang ada di Feathres, upaya pengkodean sebenarnya minimal, dan terintegrasi dengan arsitektur Feathers saat ini dengan baik. Ini membuktikan bahwa arsitektur Feathers saat ini sangat dapat diperpanjang.

Tetapi fitur lengkap dari Refresh-token juga memerlukan dukungan di sisi Klien, seperti menyimpan token penyegaran di sisi klien, Otentikasi ulang pengguna setelah token akses kedaluwarsa, logout pengguna dengan token penyegaran.

Setelah meninjau kode sumber otentikasi bulu dan klien otentikasi, saya percaya token penyegaran dapat disadap ke dalam kode Fitur yang ada berdasarkan untuk memungkinkan mengaktifkan dukungan token penyegaran semudah mengaktifkan otentikasi.

Saya sudah mem-porting basis kode token penyegaran versi kait saya ke @feathersjs/authentication. Selanjutnya saya akan mencoba membuat perubahan pada otentikasi-klien untuk mengaktifkan fitur sisi klien. Tujuan utama saya adalah mengaktifkan dukungan token penyegaran di sisi server dan klien.

Pertanyaan/kekhawatiran saya adalah bagaimana token penyegaran disimpan di klien?

Lihat https://auth0.com/blog/securing-single-page-applications-with-refresh-token-rotation/

Sayangnya, RT berumur panjang tidak cocok untuk SPA karena tidak ada mekanisme penyimpanan persisten di browser yang dapat menjamin akses hanya oleh aplikasi yang dimaksud. Karena ada kerentanan yang dapat dieksploitasi untuk mendapatkan artefak bernilai tinggi ini dan memberikan akses kepada aktor jahat ke sumber daya yang dilindungi, penggunaan token penyegaran di SPA sangat tidak disarankan.

Lihat https://afteracademy.com/blog/implement-json-web-token-jwt-authentication-using-access-token-and-refresh-token

Jadi, apa tempat terbaik untuk menyimpan token dengan aman? Anda dapat membaca lebih lanjut tentang itu di internet jika Anda bersemangat untuk mencapai penyimpanan yang sepenuhnya aman. Beberapa solusi ideal tetapi tidak terlalu praktis. Praktis saya akan menyimpannya di Cookie dengan httpOnly dan bendera Aman. Ini tidak 100 persen aman tetapi menyelesaikan pekerjaan.

Lihat diskusi panjang ini tentang cookie - https://github.com/feathersjs-ecosystem/authentication/issues/132 juga

@bwgjoseph Saya menyarankan untuk menggunakan sesi ekspres reguler, dan menyimpan semua token di sana, alih-alih sisi klien. Itulah yang saya lakukan dan berfungsi dengan baik dengan semua jenis aplikasi termasuk SPA

@sarkistlt Anda bermaksud mengatakan untuk menyimpan semua token JWT klien di sisi server? Ada referensi/bahan artikel untuk itu? Saya tidak begitu yakin bagaimana prosesnya nanti. Jadi apa yang dikirim klien, ketika mereka meminta data (CRUD)?

@bwgjoseph sama seperti biasa, cookie, cukup tambahkan middlewere sebelum mendaftarkan layanan Anda:

app.use('* | [or specific rout]', session(sess), (req, res, next) => {
      req.feathers.session = req.session || {};
      next();
    });

kemudian di server Anda, misalkan layanan login pelanggan, ketika pelanggan diautentikasi, Anda cukup menyimpan token di sesi seperti ctx.params.session.token = token , di mana token adalah akses JWT Anda atau token penyegaran, tergantung pada logika aplikasi Anda.
Dan dengan permintaan baru dari klien, Anda akan memeriksa apakah token ada di sesi dan akan menggunakannya untuk otentikasi. Ini adalah pendekatan yang jauh lebih aman dan terjamin, karena tidak ada token yang diekspos di sisi klien sama sekali.

Saya hanya akan menambahkan bahwa ini berfungsi paling baik untuk klien (browser) - aplikasi server. Saat berkomunikasi secara internal antar server, atau pekerja/server, Anda tidak memerlukan session.

Ini telah dibahas _a lot_ sebelumnya (saya juga menambahkan entri ke FAQ ) dan tidak selalu lebih aman untuk menyimpan token dalam satu sesi. Jika seseorang mendapatkan akses ke halaman Anda untuk dapat menjalankan skrip, mereka juga telah membajak sesi tersebut dan tetap dapat membuat permintaan yang diautentikasi.

Oleh karena itu, biasanya tidak masalah untuk menyimpan token di misalnya localStorage (yang hanya dapat diakses oleh halaman saat ini juga) dan juga berfungsi dengan mulus dengan platform non-browser lainnya (seperti aplikasi seluler asli, server-ke-server, dll.) __dan websockets__ (Saya tidak bisa cukup menekankan betapa menyakitkannya membuat websockets bekerja dengan mulus dan aman dengan cookie HTTP - hidup saya menjadi jauh lebih mudah sejak kami berhenti mencoba melakukannya). Secara umum, token penyegaran harus dapat dicabut karena biasanya lebih tahan lama.

Either way, permintaan tarik untuk ini akan sangat diterima, saya merasa itu membuat menyetrika detailnya jauh lebih mudah.

@jackywxd -
Apakah ada cara untuk memudahkan pengembang mengimplementasikan ini?
Seperti mengintegrasikan kait yang Anda buat ke dalam perpustakaan, jadi kita tidak perlu menambahkan kait nanti?

Saya pikir Anda harus membuat permintaan tarik dan kita bisa berdiskusi di sana.

@daffl ya setuju, terutama dengan WS. Dan jika klien dan backend dibangun oleh Anda atau tim Anda, ya sebaiknya gunakan JWT saja dan hindari ketergantungan dan kerumitan tambahan dalam aplikasi Anda.
Tetapi dalam beberapa kasus, misalnya ketika membangun REST-API etalase yang akan digunakan oleh perusahaan/pengembang pihak ke-3, lebih mudah menggunakan sesi reguler, dan meminta pengembang untuk menyertakan kredensial dengan permintaan mereka kemudian menjelaskan cara mengambil akses (dan menyegarkan ) token, simpan, dan berikan dengan setiap permintaan. Yang ditangani dengan sempurna oleh klien bulu, tetapi dalam kebanyakan kasus ketika pengembang tidak terbiasa dengan bagaimana backend dibangun, mereka akan menggunakan request, superagent, fetch or axios untuk menghubungkan aplikasi mereka ke backend. Setidaknya dalam kasus saya, ini adalah alasan utama untuk memindahkan bagian etalase API agar berfungsi dengan sesi reguler alih-alih JWT secara langsung.

Tetapi bukankah itu keputusan dan tanggung jawab desain, pembuat etalase tersebut, untuk mengimplementasikan ke dalam API mereka sendiri dan kemudian mendokumentasikan fitur ini dengan benar, alih-alih "memaksa" keputusan ini ke komunitas?

@TheSinding Saya pikir kita bisa mengatakan 'memaksa' tentang pendekatan yang kurang umum digunakan, bukan tentang cookie yang telah (dan masih) pendekatan yang paling umum digunakan untuk mengelola sesi pengguna.

Dan ya itu adalah keputusan desain yang dibuat setelah umpan balik pengembang yang telah menggunakan API. Saat Anda menjalankan sistem multi-penyewa atau API yang digunakan oleh banyak tim, terkadang yang terbaik adalah mengikuti praktik industri umum untuk menghindari kebingungan tambahan dan waktu ekstra yang dihabiskan oleh pengembang, terutama jika solusi alternatif tidak memberikan keuntungan apa pun bagi pengguna akhir.

Sekali lagi untuk menjadi jelas, menggunakan JWT itu hebat, dan cara yang lebih mudah untuk digunakan terutama untuk API waktu nyata dan itulah yang kami gunakan dalam 90% kasus + Anda tidak perlu menjalankan redis atau sesuatu yang lain untuk mengelola sesi cookie.
Tetapi ada beberapa kasus luar biasa di mana itu mungkin bukan pilihan terbaik, saya membawa contoh situasi itu di komentar saya sebelumnya.

Saya tidak mengatakan Anda salah, saya hanya berpikir "dengan keras" :)

IMO, saya pikir pendekatan dengan JWT akan menjadi pendekatan yang lebih baik, karena itulah yang sudah didukung dan sebagai @daffl juga lebih mudah untuk dikerjakan

Terima kasih atas semua tanggapan Anda! JWT vs sesi adalah topik berbeda yang bisa kita diskusikan secara terpisah.

Saya pikir satu hal yang kita semua setuju adalah bahwa token akses + token penyegaran adalah solusi yang jauh lebih aman daripada sekadar token akses. Ini telah diadopsi secara luas oleh raksasa Internet besar. Adalah adil untuk mengatakan bahwa komunitas Feathers akan senang melihat basis kode utama Feathers untuk menyediakan dukungan bawaan untuk token penyegaran. Sebenarnya itu mengejutkan saya ketika saya pertama kali menyadari bahwa Feathers tidak mendukung token penyegaran.

Saya telah menggunakan AWS cognito di beberapa proyek saya, AWS Amplify akan menyimpan tiga token di Penyimpanan lokal: token ID, token akses dan token penyegaran, Amplify menangani semua pekerjaan kotor yang terkait dengan manajemen token, dan menyediakan beberapa API yang memungkinkan kemudahan dan antarmuka lurus ke depan bekerja dengan backend Cognito. Saya ingin melihat pengalaman pengembangan serupa dengan Feathers.

@TheSinding Terima kasih atas pekerjaan hebat Anda sebelumnya!

Karena otentikasi yang ada diimplementasikan sebagai layanan normal, kami dapat dengan mudah mengaktifkan dukungan token penyegaran dengan memperluas kelas dan menambahkan beberapa kait:

this.hooks({ after: { create: [issueRefreshToken(), connection('login'), event('login')], remove: [logoutUser(), connection('logout'), event('logout')], patch: [refreshAccessToken()], },

Sama seperti kami mengaktifkan Otentikasi dengan menggunakan CLI, kami dapat menawarkan opsi serupa di CLI untuk dukungan token penyegaran. pengembang cukup menjawab YA, CLI kemudian secara otomatis membuat layanan "token penyegaran" pelanggan dan memperbarui konfigurasi terkait token penyegaran dalam file konfigurasi default. Jadi ini seperti solusi turn-key untuk pengembang.

@daffl David, terima kasih telah membuat Bulu! hanya ingin tahu apakah ada "panduan berkontribusi", "pedoman pengkodean", "panduan gaya" untuk Feathers?

Seperti yang saya sebutkan sebelumnya, PR dengan implementasi untuk token penyegaran (atau bahkan hanya beberapa ide) akan sangat disambut. Saya belum sempat memeriksa repo tertaut dan diskusi ini menjadi cukup panjang. Memiliki semuanya terkini dan di satu tempat akan membuat segalanya jauh lebih mudah. Beberapa poin penting:

  • Token penyegaran dapat dikeluarkan dengan memperluas Layanan Otentikasi
  • Token penyegaran harus disimpan di Penyimpanan lokal
  • Token penyegaran harus dapat dibatalkan (jadi perlu ada implementasi tujuan yang lebih umum dari mekanisme pencabutan yang dijelaskan di https://docs.feathersjs.com/cookbook/authentication/revoke-jwt.html)
  • Karena kerumitan dan pengaturan tambahan (seperti Redis untuk menyimpan token yang dicabut), itu dapat tersedia sebagai fitur tetapi tidak boleh diaktifkan secara default (yaitu aplikasi yang dibuat standar - dapat menjadi bagian dari CLI tetapi sebelum melakukan apa pun tentang itu, Saya masih sangat mencari bantuan dalam memulai generator berbasis hygen )
  • Info kontribusi dapat ditemukan di panduan kontributor

Jika seseorang menggunakan refreshToken, kami membuat perpustakaan yang menangani di frontend, accessToken dan refreshToken seperti "sesi", terlalu mudah digunakan.

Hanya perlu melewati token dan perpustakaan mencoba mendapatkan acessToken baru dengan refreshToken ketika akan kedaluwarsa. Saat ini digunakan di Videsk .

Repositori: Pengendali Otentikasi Depan

Apakah halaman ini membantu?
0 / 5 - 0 peringkat