एक पुस्तकालय का उपयोग किए बिना जावास्क्रिप्ट में jwt टोकन को कैसे डिकोड किया जाए?


208

मैं जावास्क्रिप्ट का उपयोग करके JWT के पेलोड को कैसे कम कर सकता हूं? बिना पुस्तकालय के। तो टोकन सिर्फ एक पेलोड ऑब्जेक्ट देता है जो मेरे फ्रंट-एंड ऐप द्वारा उपभोग किया जा सकता है।

उदाहरण टोकन: xxxxxxxxx.XXXXXXXX.xxxxxxxx

और परिणाम पेलोड है:

{exp: 10012016 name: john doe, scope:['admin']}

1
यह कैसे एनकोडेड था? बस उल्टा करते हैं। आपको साझा रहस्य की आवश्यकता होगी।
लकी सोनी

यह बैकएंड एपी द्वारा एन्कोड किया गया था जो php लाइब्रेरी का उपयोग करता था। यहाँ मैं जरूरत पेलोड है कि base64 का उपयोग कर एन्कोडेड है मुझे लगता है ...
Chrisk8er

1
आप jwt.io वेबसाइट पर जाने और इसे प्रदान करने वाली जावास्क्रिप्ट लाइब्रेरी प्राप्त करने का प्रयास कर सकते हैं ।
क्वेंटिन

12
चूंकि इस प्रश्न में कुछ ट्रैफ़िक है, इसलिए मैं एक डिस्क्लेमर जोड़ना चाहता हूं: यदि आप हस्ताक्षर को सत्यापित किए बिना, टोकन के पेलोड को नेत्रहीन रूप से डिकोड करते हैं, तो आप सुरक्षा मुद्दों में भाग ले सकते हैं (या नहीं)! सुनिश्चित करें कि आप इस स्टैकओवरफ़्लो प्रश्न में दिए गए किसी भी कोड का आँख बंद करके उपयोग करने से पहले अपनी सुरक्षा वास्तुकला को समझ लें।
कार्स्टन हॉफमैन

4
@CarstenHoffmann और मैं वास्तव में हस्ताक्षर को कैसे सत्यापित करूँ ??
सौरभ तिवारी

जवाबों:


468

कार्य यूनिकोड पाठ JWT पार्सर फ़ंक्शन:

function parseJwt (token) {
    var base64Url = token.split('.')[1];
    var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
    var jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
    }).join(''));

    return JSON.parse(jsonPayload);
};

2
दुर्भाग्य से यह यूनिकोड पाठ के साथ काम नहीं करता है।
पॉल मैकमोहन

2
इस समाधान का उपयोग पोस्टमैन (परीक्षण टैप) में भी किया जा सकता है क्योंकि इसके लिए किसी भी अतिरिक्त लाइब्रेरी इंस्टॉलेशन की आवश्यकता नहीं होती है। मैंने इसका उपयोग उपयोगकर्ता-प्राप्त को टोकन से टोकन निकालने के लिए किया था।
व्लाद

2
नोट: पोस्टमैन में मुझे JSON.parse(window.atob(base64))इसे काम करने के लिए "विंडो" को हटाना पड़ा । बस return JSON.parse(atob(base64));और फिर postman.setEnvironmentVariable("userId", parseJwt(jsonData.access_token)); "access_token" मेरे मामले में प्रतिक्रिया में टोकन के मूल्य की कुंजी है (आपके मामले में भिन्न हो सकती है)।
व्लाद

12
उपरोक्त समाधान केवल टोकन में पहले "-" और "_" को प्रतिस्थापित करता है (एक जावास्क्रिप्ट "फीचर" जो मुझे दर्द देता रहता है)। बस तीसरी पंक्ति को उत्तर में बदलें:var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
टैडपोल

2
jwt-decodeमॉड्यूल का उपयोग करना बेहतर है क्योंकि यह छोटा है लेकिन थोड़ा अधिक बेहतर हैंडलिंग है।
रांटिव

64

कोशिश के साथ सरल कार्य - पकड़

const parseJwt = (token) => {
  try {
    return JSON.parse(atob(token.split('.')[1]));
  } catch (e) {
    return null;
  }
};

धन्यवाद!


अच्छा, संक्षिप्त और सभी देशी तरीकों का उपयोग करता है!
क्रिस लव


47

आप jwt-decode का उपयोग कर सकते हैं , तो आप लिख सकते हैं:

import jwt_decode from 'jwt-decode';

var token = 'eyJ0eXAiO.../// jwt token';

var decoded = jwt_decode(token);
console.log(decoded);
/*{exp: 10012016 name: john doe, scope:['admin']}*/

66
"मेरा मतलब है कोई पुस्तकालय नहीं।"
शर्लोकटीवी

उन्हें इस लाइब्रेरी से समस्या है। मुख्य रूप से उपयोग में फ़ायरफ़ॉक्स के साथ। समस्या है कि मैं भाग गया था कि अगर एक टोकन == अशक्त लॉग आउट या निष्कासन से उत्पन्न; यह सिर्फ एक त्रुटि के साथ पृष्ठ को मारता है।
लउसर

1
@ApertureSecurity आपको इस त्रुटि को पकड़ने की आवश्यकता है, लेकिन माना जाता है कि मैं इस पुस्तकालय का उपयोग नहीं करना चाहता हूं
ल्यूक रॉबर्टसन

यह GZIP का समर्थन नहीं करता है। वास्तव में, मुझे कोई जेएस लाइब्रेरी नहीं मिल रही है जो दावों के लिए GZIP का समर्थन करती है।
एंड्रयू टी फिनेल

18

आप atob()स्ट्रिंग में डिकोड करने के लिए शुद्ध जावास्क्रिप्ट फ़ंक्शन का उपयोग कर सकते हैं :

atob(token.split('.')[1]);

या इसे सीधे एक जॅसन ऑब्जेक्ट में पार्स करें:

JSON.parse(atob(token.split('.')[1]));

के बारे में atob()और btoa()निर्मित जावास्क्रिप्ट कार्य Base64 एन्कोडिंग और डिकोडिंग के बारे में पढ़ें - वेब एपीआई | एमडीएन


9

@ पेहेजे काम करेगा, लेकिन आपको यूनिकोड के साथ समस्या होगी। इसे ठीक करने के लिए मैं https://stackoverflow.com/a/30106551/5277071 पर कोड का उपयोग करता हूं ;

let b64DecodeUnicode = str =>
  decodeURIComponent(
    Array.prototype.map.call(atob(str), c =>
      '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
    ).join(''))

let parseJwt = token =>
  JSON.parse(
    b64DecodeUnicode(
      token.split('.')[1].replace('-', '+').replace('_', '/')
    )
  )


let form = document.getElementById("form")
form.addEventListener("submit", (e) => {
   form.out.value = JSON.stringify(
      parseJwt(form.jwt.value)
   )
   e.preventDefault();
})
textarea{width:300px; height:60px; display:block}
<form id="form" action="parse">
  <textarea name="jwt">eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkrDtGhuIETDs8OoIiwiYWRtaW4iOnRydWV9.469tBeJmYLERjlKi9u6gylb-2NsjHLC_6kZNdtoOGsA</textarea>
  <textarea name="out"></textarea>
  <input type="submit" value="parse" />
</form>


+1 लेकिन अगर पेहजे के जवाब पर रेसिंग टैडपोल की टिप्पणी सही है (कि प्रतिस्थापित कॉल केवल पहले उदाहरण को बदल देगा), तो वही फिक्स यहां लागू होगा।
गैरी मैकगिल

9

नोड विंडो के वातावरण में "विंडो" ऑब्जेक्ट मौजूद नहीं है, हम कोड की निम्न पंक्तियों का उपयोग कर सकते हैं:

let base64Url = token.split('.')[1]; // token you get
let base64 = base64Url.replace('-', '+').replace('_', '/');
let decodedData = JSON.parse(Buffer.from(base64, 'base64').toString('binary'));

यह मेरे लिए पूरी तरह से काम कर रहा है। आशा करता हूँ की ये काम करेगा।


1
नोड जेएस के लिए सही उत्तर
०१४: ०१:

7
function parseJwt(token) {
  var base64Payload = token.split('.')[1];
  var payload = Buffer.from(base64Payload, 'base64');
  return JSON.parse(payload);
}
let payload= parseJwt("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c");
console.log("payload:- ", payload);

नोड का उपयोग करते समय, आपको बफर पैकेज का उपयोग करना पड़ सकता है:

npm install buffer
var Buffer = require('buffer/').Buffer

6

मैं इस फ़ंक्शन का उपयोग इस उत्तर के आधार पर पेलोड, हेडर, एक्सप (समय समाप्ति), iat (जारी) पर प्राप्त करने के लिए करता हूं

function parseJwt(token) {
  try {
    // Get Token Header
    const base64HeaderUrl = token.split('.')[0];
    const base64Header = base64HeaderUrl.replace('-', '+').replace('_', '/');
    const headerData = JSON.parse(window.atob(base64Header));

    // Get Token payload and date's
    const base64Url = token.split('.')[1];
    const base64 = base64Url.replace('-', '+').replace('_', '/');
    const dataJWT = JSON.parse(window.atob(base64));
    dataJWT.header = headerData;

// TODO: add expiration at check ...


    return dataJWT;
  } catch (err) {
    return false;
  }
}

const jwtDecoded = parseJwt('YOUR_TOKEN') ;
if(jwtDecoded)
{
    console.log(jwtDecoded)
}

यह उत्तर कुछ हद तक बेहतर है, लेकिन इसमें ढाई मुद्दे हैं। सबसे पहले, यह हस्ताक्षर (सरणी आइटम 2) की जांच नहीं करता है। दूसरा, REPLACE सही ढंग से काम नहीं करेंगे, क्योंकि वे regex पर "g" ध्वज को याद करते हैं (केवल JWT पर - और _ की पहली घटनाओं को प्रतिस्थापित करेंगे, जैसे रेसिंग टैडपोल ने किसी अन्य पोस्ट पर टिप्पणी की थी)। और आधा: सरणी आइटम 0 और 1 को डीकोड करने के लिए, आप पूरे कोड को डुप्लिकेट करने के बजाय एक लूप का उपयोग कर सकते थे (यह एक छोटा कोड है, लेकिन इसे अधिक कुशल बनाया जा सकता है, जिस तरह से यह है, SPLIT दो बार निष्पादित होता है )।
साइबरनाइट

4

jwt.io की सभी विशेषताएं सभी भाषाओं का समर्थन नहीं करती हैं। NodeJs में आप उपयोग कर सकते हैं

var decoded = jwt.decode(token);

1
पुस्तकालय के बिना आप बस टोकन के दूसरे भाग में base64 डिकोडिंग करते हैं {var पेलोड = token.split ('।') [1]); } इसके बाद base64 डिकोडिंग प्रदर्शन करें {var decodedData = atob (पेलोड); }
जितिन विजयन

4

मुझे यह कोड jwt.io पर मिला और यह अच्छी तरह से काम करता है।

//this is used to parse base64
function url_base64_decode(str) {
  var output = str.replace(/-/g, '+').replace(/_/g, '/');
  switch (output.length % 4) {
    case 0:
      break;
    case 2:
      output += '==';
      break;
    case 3:
      output += '=';
      break;
    default:
      throw 'Illegal base64url string!';
  }
  var result = window.atob(output); //polifyll https://github.com/davidchambers/Base64.js
  try{
    return decodeURIComponent(escape(result));
  } catch (err) {
    return result;
  }
}

कुछ मामलों में (कुछ विकास प्लेटफार्मों),
सबसे अच्छा उत्तर (अभी के लिए) अमान्य base64 लंबाई की समस्या का सामना करता है।
इसलिए, मुझे और अधिक स्थिर तरीके की आवश्यकता थी।

मुझे उम्मीद है कि यह आपकी मदद करेगा।


2

गाइ और पेहेजे दोनों ने पहले ही सवाल का जवाब दिया। मेरे जैसे कुल शुरुआत करने वालों के लिए यह उदाहरण के रूप में आयात रेखा को परिभाषित करने में सहायक था।

इसके अलावा मुझे यह पता लगाने में कुछ मिनट लगे कि टोकन क्रेडेंशियल का पूरा सेट है जो वापस पोस्ट हो जाता है (पूरे जेडब्ल्यूटी टोकन, न कि केवल आईडीटोन भाग)। एक बार जब आप इसे जान लेते हैं ..

import jwt_decode from 'jwt-decode';

var token = 'eyJ0eXAiO.../// jwt token';
var decoded = jwt_decode(token);

/*{exp: 10012016 name: john doe, scope:['admin']}*/


2
ठीक उसी उत्तर को किसी अन्य उपयोगकर्ता के रूप में पोस्ट करना, जो ओपी के लिए जो कुछ कहता है, वह बहुत मददगार नहीं है
कैकून

2

JSON वेब टोकन (JWT) को डिकोड करने के लिए सरल NodeJS समाधान

function decodeTokenComponent(value) {
    const buff = new Buffer(value, 'base64')
    const text = buff.toString('ascii')
    return JSON.parse(text)
}

const token = 'xxxxxxxxx.XXXXXXXX.xxxxxxxx'
const [headerEncoded, payloadEncoded, signature] = token.split('.')
const [header, payload] = [headerEncoded, payloadEncoded].map(decodeTokenComponent)

console.log(`header: ${header}`)
console.log(`payload: ${payload}`)
console.log(`signature: ${signature}`)

2

GitHub से आधारित उत्तर - schem0 / jwt-decode । स्ट्रिंग स्प्लिटिंग और रिटर्न ऑब्जेक्ट {हेडर, पेलोड, सिग्नेचर} को शामिल करने के लिए इनपुट / आउटपुट को बदल दिया ताकि आप पूरे टोकन को पास कर सकें।

var jwtDecode = function (jwt) {

        function b64DecodeUnicode(str) {
            return decodeURIComponent(atob(str).replace(/(.)/g, function (m, p) {
                var code = p.charCodeAt(0).toString(16).toUpperCase();
                if (code.length < 2) {
                    code = '0' + code;
                }
                return '%' + code;
            }));
        }

        function decode(str) {
            var output = str.replace(/-/g, "+").replace(/_/g, "/");
            switch (output.length % 4) {
                case 0:
                    break;
                case 2:
                    output += "==";
                    break;
                case 3:
                    output += "=";
                    break;
                default:
                    throw "Illegal base64url string!";
            }

            try {
                return b64DecodeUnicode(output);
            } catch (err) {
                return atob(output);
            }
        }

        var jwtArray = jwt.split('.');

        return {
            header: decode(jwtArray[0]),
            payload: decode(jwtArray[1]),
            signature: decode(jwtArray[2])
        };

    };

1

इस प्रश्न का अध्ययन करने के बाद मैंने एक और सुविधा संपन्न समाधान प्रस्तुत किया है:

const parseJwt = (token) => {
    try {
        if (!token) {
            throw new Error('parseJwt# Token is required.');
        }

        const base64Payload = token.split('.')[1];
        let payload = new Uint8Array();

        try {
            payload = Buffer.from(base64Payload, 'base64');
        } catch (err) {
            throw new Error(`parseJwt# Malformed token: ${err}`);
        }

        return {
            decodedToken: JSON.parse(payload),
        };
    } catch (err) {
        console.log(`Bonus logging: ${err}`);

        return {
            error: 'Unable to decode token.',
        };
    }
};

यहाँ कुछ उपयोग नमूने हैं:

const unhappy_path1 = parseJwt('sk4u7vgbis4ewku7gvtybrose4ui7gvtmalformedtoken');
console.log('unhappy_path1', unhappy_path1);

const unhappy_path2 = parseJwt('sk4u7vgbis4ewku7gvtybrose4ui7gvt.malformedtoken');
console.log('unhappy_path2', unhappy_path2);

const unhappy_path3 = parseJwt();
console.log('unhappy_path3', unhappy_path3);

const { error, decodedToken } = parseJwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c');
if (!decodedToken.exp) {
    console.log('almost_happy_path: token has illegal claims (missing expires_at timestamp)', decodedToken);
    // note: exp, iat, iss, jti, nbf, prv, sub
}

मैं StackOverflow कोड स्निपेट टूल में उस रन करने योग्य को बनाने में सक्षम नहीं था, लेकिन यहाँ आप लगभग उस कोड को चलाने पर क्या देखेंगे।

यहां छवि विवरण दर्ज करें

मैंने parseJwtफ़ंक्शन को हमेशा एक वस्तु (कुछ हद तक स्थैतिक-टाइपिंग कारणों के लिए) वापस किया।

यह आपको सिंटैक्स का उपयोग करने की अनुमति देता है जैसे:

const { decodedToken, error } = parseJwt(token);

फिर आप विशिष्ट प्रकार की त्रुटियों के लिए रन-टाइम पर परीक्षण कर सकते हैं और किसी भी नामकरण टकराव से बच सकते हैं।

यदि कोई भी किसी भी कम प्रयास के बारे में सोच सकता है, तो इस कोड में उच्च मूल्य परिवर्तन होता है, बेझिझक मेरे उत्तर को लाभ के लिए संपादित करें next(person)


0

यहाँ और यहाँ उत्तर के आधार पर :

const dashRE = /-/g;
const lodashRE = /_/g;

module.exports = function jwtDecode(tokenStr) {
  const base64Url = tokenStr.split('.')[1];
  if (base64Url === undefined) return null;
  const base64 = base64Url.replace(dashRE, '+').replace(lodashRE, '/');
  const jsonStr = Buffer.from(base64, 'base64').toString();
  return JSON.parse(jsonStr);
};

-1

रनिंग जावास्क्रिप्ट नोड.जेएस एक्सप्रेस मुझे पहले पैकेज को निम्नानुसार स्थापित करना था:

npm install jwt-decode --save

तब मेरे app.js कोड में पैकेज मिलता है:

const jwt_decode = require('jwt-decode');

फिर कोड चलाएँ:

let jwt_decoded = jwt_decode(jwt_source);

फिर जादू:

console.log('sub:',jwt_decoded.sub);

4
याद रखें "एक पुस्तकालय का उपयोग किए बिना"
ओलाफ

1
ठीक है पर्याप्त ठीक है। हालाँकि, मैं एक ही समस्या का सामना कर रहा था और मेरे पास पुस्तकालय का उपयोग न करने का प्रतिबंध नहीं था। इसने मेरे लिए काम किया। मैं इसे पोस्ट करता हूं क्योंकि शायद कोई और इसी तरह के मुद्दे का सामना करता है और इसमें कोई प्रतिबंध नहीं है।
डेविड व्हाइट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.