ग्राफकलाइन - प्रमाणिक ग्राहक

प्रमाणीकरण एक उपयोगकर्ता या एक प्रक्रिया की पहचान की पुष्टि करने की प्रक्रिया या क्रिया है। यह महत्वपूर्ण है कि एक एप्लिकेशन एक उपयोगकर्ता को यह सुनिश्चित करने के लिए प्रमाणित करता है कि डेटा अनाम उपयोगकर्ता के लिए उपलब्ध नहीं है। इस खंड में, हम सीखेंगे कि एक ग्राफक्यूएल क्लाइंट को कैसे प्रमाणित किया जाए।

एक्सप्रेस JWT

इस उदाहरण में, हम क्लाइंट एप्लिकेशन बनाने के लिए jQuery का उपयोग करेंगे। अनुरोधों को प्रमाणित करने के लिए, हम उपयोग करेंगे express-jwt सर्वर-साइड पर मॉड्यूल।

एक्सप्रेस- jwt मॉड्यूल एक मिडलवेयर है जो आपको JWT टोकन का उपयोग करके HTTP अनुरोधों को प्रमाणित करने देता है। JSON वेब टोकन (JWT) एक लंबी स्ट्रिंग है जो उपयोगकर्ता में लॉग इन की पहचान करता है।

एक बार जब उपयोगकर्ता सफलतापूर्वक लॉग इन करता है, तो सर्वर एक JWT टोकन बनाता है। यह टोकन विशिष्ट रूप से लॉग की पहचान करता है। दूसरे शब्दों में, टोकन उपयोगकर्ता की पहचान का प्रतिनिधित्व करता है। इसलिए अगली बार, जब क्लाइंट सर्वर पर आता है, तो उसे आवश्यक संसाधन प्राप्त करने के लिए इस टोकन को प्रस्तुत करना होता है। क्लाइंट या तो मोबाइल एप्लिकेशन या वेब एप्लिकेशन हो सकता है।

चित्रण

हम इस दृष्टांत को समझने के लिए एक चरण-वार प्रक्रिया का पालन करेंगे।

सर्वर की स्थापना

सर्वर स्थापित करने के लिए निम्नलिखित चरण हैं -

चरण 1 - परियोजना के लिए आवश्यक निर्भरताएँ डाउनलोड और स्थापित करें

एक फ़ोल्डर बनाएँ auth-server-app। अपनी निर्देशिका को बदलें auth-server-app टर्मिनल से। पर्यावरण सेटअप अध्याय में समझाया गया चरण 3 से 5 का पालन करें।

चरण 2 - एक स्कीमा बनाएं

जोड़ना schema.graphql प्रोजेक्ट फ़ोल्डर में फ़ाइल auth-server-app और निम्नलिखित कोड जोड़ें -

type Query
{
   greetingWithAuth:String
}

चरण 3 - रिज़ॉल्वर जोड़ें

एक फ़ाइल बनाएँ resolvers.js प्रोजेक्ट फ़ोल्डर में और निम्न कोड जोड़ें -

रिज़ॉल्वर सत्यापित करेगा कि ग्राफिंक के संदर्भ ऑब्जेक्ट में एक प्रमाणित उपयोगकर्ता ऑब्जेक्ट उपलब्ध है या नहीं। यदि कोई प्रमाणित उपयोगकर्ता उपलब्ध नहीं है तो यह एक अपवाद को बढ़ाएगा।

const db = require('./db')

const Query = {
   greetingWithAuth:(root,args,context,info) => {

      //check if the context.user is null
      if (!context.user) {
         throw new Error('Unauthorized');
      }
      return "Hello from TutorialsPoint, welcome back : "+context.user.firstName;
   }
}

module.exports = {Query}

चरण 4 - Server.js फ़ाइल बनाएँ

प्रमाणीकरण मिडलवेयर एक JSON वेब टोकन का उपयोग करके कॉलर्स को प्रमाणित करता है। प्रमाणीकरण के लिए URL है http://localhost:9000/login

यह एक पोस्ट ऑपरेशन है। उपयोगकर्ता को अपना ईमेल और पासवर्ड जमा करना होगा जो बैकएंड से मान्य होगा। यदि jwt.sign विधि का उपयोग करके एक वैध टोकन उत्पन्न होता है, तो क्लाइंट को बाद के अनुरोधों के लिए हेडर में भेजना होगा।

यदि टोकन वैध है, तो req.user को JSON ऑब्जेक्ट के साथ सेट किया जाएगा जिसे प्राधिकरण और अभिगम नियंत्रण के लिए बाद के मिडलवेयर द्वारा उपयोग किए जाने के लिए डिकोड किया जाएगा।

निम्नलिखित कोड दो मॉड्यूल का उपयोग करता है - अनुरोधों को प्रमाणित करने के लिए jsonwebtoken और एक्सप्रेस- jwt -

  • जब उपयोगकर्ता क्लिक करता है greetबटन, / रेखांकन मार्ग के लिए एक अनुरोध जारी किया जाता है। यदि उपयोगकर्ता प्रमाणित नहीं है, तो उसे खुद को प्रमाणित करने के लिए प्रेरित किया जाएगा।

  • उपयोगकर्ता को ईमेल आईडी और पासवर्ड स्वीकार करने वाले फॉर्म के साथ प्रस्तुत किया जाता है। हमारे उदाहरण में, उपयोगकर्ता को प्रमाणित करने के लिए / लॉगिन मार्ग जिम्मेदार है।

  • यदि उपयोगकर्ता द्वारा प्रदान की गई क्रेडेंशियल के लिए डेटाबेस में कोई मेल मिलता है, तो / लॉगिन मार्ग सत्यापित करता है।

  • यदि क्रेडेंशियल अमान्य हैं, तो उपयोगकर्ता के लिए एक HTTP 401 अपवाद वापस आ गया है।

  • यदि क्रेडेंशियल मान्य हैं, तो सर्वर द्वारा एक टोकन जनरेट किया जाता है। यह टोकन उपयोगकर्ता की प्रतिक्रिया के एक भाग के रूप में भेजा जाता है। यह jwt.sign फ़ंक्शन द्वारा किया जाता है।

const expressJwt = require('express-jwt');
const jwt = require('jsonwebtoken');

//private key
const jwtSecret = Buffer.from('Zn8Q5tyZ/G1MHltc4F/gTkVJMlrbKiZt', 'base64');

app.post('/login', (req, res) => {
   const {email, password} = req.body;
   
   //check database
   const user = db.students.list().find((user) =>  user.email === email);
   if (!(user && user.password === password)) {
      res.sendStatus(401);
      return;
   }
   
   //generate a token based on private key, token doesn't have an expiry
   const token = jwt.sign({sub: user.id}, jwtSecret);
   res.send({token});
});

प्रत्येक अनुरोध के लिए, app.use () फ़ंक्शन को बुलाया जाएगा। यह बदले में expressJWT मिडलवेयर को आमंत्रित करेगा। यह मिडलवेयर JSON वेब टोकन को डिकोड करेगा। टोकन में संग्रहीत उपयोगकर्ता आईडी को पुनः प्राप्त किया जाएगा और अनुरोध ऑब्जेक्ट में एक संपत्ति उपयोगकर्ता के रूप में संग्रहीत किया जाएगा।

//decodes the JWT and stores in request object
app.use(expressJwt({
   secret: jwtSecret,
   credentialsRequired: false
}));

ग्राफकॉल संदर्भ के भीतर उपयोगकर्ता संपत्ति उपलब्ध कराने के लिए, यह संपत्ति को सौंपा गया है context नीचे दिखाए अनुसार वस्तु -

//Make req.user available to GraphQL context
app.use('/graphql', graphqlExpress((req) => ({
   schema,
   context: {user: req.user &&apm; db.students.get(req.user.sub)}
})));

सृजन करना server.js वर्तमान फ़ोल्डर पथ में। पूरा server.js फ़ाइल इस प्रकार है -

const bodyParser = require('body-parser');
const cors = require('cors');
const express = require('express');
const expressJwt = require('express-jwt'); //auth
const jwt = require('jsonwebtoken'); //auth
const db = require('./db');

var port = process.env.PORT || 9000
const jwtSecret = Buffer.from('Zn8Q5tyZ/G1MHltc4F/gTkVJMlrbKiZt', 'base64');
const app = express();

const fs = require('fs')
const typeDefs = fs.readFileSync('./schema.graphql',{encoding:'utf-8'})
const resolvers = require('./resolvers')
const {makeExecutableSchema} = require('graphql-tools')

const schema = makeExecutableSchema({typeDefs, resolvers})

app.use(cors(), bodyParser.json(), expressJwt({
   secret: jwtSecret,
   credentialsRequired: false
}));

const  {graphiqlExpress,graphqlExpress} = require('apollo-server-express')

app.use('/graphql', graphqlExpress((req) => ({
   schema,
   context: {user: req.user && db.students.get(req.user.sub)}
})));
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))

//authenticate students
app.post('/login', (req, res) => {
   const email = req.body.email;
   const password = req.body.password;

   const user = db.students.list().find((user) =>  user.email === email);
   if (!(user && user.password === password)) {
      res.sendStatus(401);
      return;
   }
   const token = jwt.sign({sub: user.id}, jwtSecret);
   res.send({token});
});

app.listen(port, () => console.info(`Server started on port ${port}`));

चरण 5 - एप्लिकेशन को चलाएं

टर्मिनल में कमांड  npm शुरू करें। सर्वर 9000 पोर्ट पर अप और रनिंग होगा। यहाँ, हम अनुप्रयोग का परीक्षण करने के लिए एक ग्राहक के रूप में ग्राफिंक का उपयोग करते हैं।

ब्राउज़र खोलें और URL टाइप करें http://localhost:9000/graphiql। संपादक में निम्नलिखित प्रश्न टाइप करें -

{
   greetingWithAuth
}

नीचे की प्रतिक्रिया में, हमें एक त्रुटि मिली क्योंकि हम प्रमाणित उपयोगकर्ता नहीं हैं।

{
   "data": {
      "greetingWithAuth": null
   },
   "errors": [
      {
         "message": "Unauthorized",
         "locations": [
            {
               "line": 2,
               "column": 3
            }
         ],
         "path": [
            "greetingWithAuth"
         ]
      }
   ]
}

अगले भाग में, आइए हम प्रमाणित करने के लिए एक ग्राहक एप्लिकेशन बनाएँ।

JQuery क्लाइंट की स्थापना

क्लाइंट एप्लिकेशन में, एक ग्रीटिंग बटन प्रदान किया जाता है जो स्कीमा को लागू करेगा greetingWithAuth। यदि आप बिना लॉगिन के बटन पर क्लिक करते हैं, तो यह आपको नीचे दिए गए त्रुटि संदेश देगा -

एक बार जब आप डेटाबेस में उपलब्ध उपयोगकर्ता के साथ लॉग इन करते हैं, तो निम्न स्क्रीन दिखाई देगी -

उपयोग करने के लिए greeting, हमें पहले URL का उपयोग करने की आवश्यकता है http://localhost:9000/login नीचे के रूप में मार्ग।

प्रतिक्रिया में सर्वर से उत्पन्न टोकन होगा।

$.ajax({
   url:"http://localhost:9000/login",
   contentType:"application/json",
   type:"POST",
   data:JSON.stringify({email,password}),
   success:function(response) {
      loginToken = response.token;
      $('#authStatus')
      .html("authenticated successfully")
      .css({"color":"green",'font-weight':'bold'});
      $("#greetingDiv").html('').css({'color':''});
   },
   error:(xhr,err) =>  alert('error')
})

एक सफल लॉगिन के बाद, हम नीचे दिए गए अनुसार ग्रीटिंगविथ स्कीमा का उपयोग कर सकते हैं। वाहक टोकन के साथ सभी बाद के अनुरोधों के लिए एक प्राधिकरण होना चाहिए।

{ 
   url: "http://localhost:9000/graphql",
   contentType: "application/json",
   headers: {"Authorization": 'bearer '+loginToken},  type:'POST',
   data: JSON.stringify({
   query:`{greetingWithAuth}`
}

Index.html के लिए निम्नलिखित कोड है -

<!DOCTYPE html>
<html>
   <head>
      <script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      <script>
         $(document).ready(function() {
            let loginToken = "";
            $("#btnGreet").click(function() {
                  $.ajax({url: "http://localhost:9000/graphql",
                  contentType: "application/json",
                  headers: {"Authorization": 'bearer '+loginToken},
                  type:'POST',
                  data: JSON.stringify({
                  query:`{greetingWithAuth}` }),
                  success: function(result) {
                  $("#greetingDiv").html("<h1>"+result.data.greetingWithAuth+"</h1>")
                  },
                  error:function(jQxhr,error) {
                     if(jQxhr.status == 401) {
                        $("#greetingDiv").html('please authenticate first!!')
                        .css({"color":"red",'font-weight':'bold'})
                        return;
                     }
                     $("#greetingDiv").html('error').css("color","red");
                  }
               });
            });
            $('#btnAuthenticate').click(function() {
               var email =  $("#txtEmail").val();
               var password =  $("#txtPwd").val();
               if(email && password) {
                  $.ajax({
                     url:"http://localhost:9000/login",
                     contentType:"application/json",
                     type:"POST",
                     data:JSON.stringify({email,password}),
                     success:function(response) {
                        loginToken =  response.token;
                        $('#authStatus')
                        .html("authenticated successfully")
                        .css({"color":"green",'font-weight':'bold'});
                        $("#greetingDiv").html('').css({'color':''});
                     },
                     error:(xhr,err) =>  alert('error')
                  })
               }else alert("email and pwd empty")
            })
         });
      </script>
   </head>
   
   <body>
      <h1> GraphQL Authentication </h1>
      <hr/>
      <section>
         <button id = "btnGreet">Greet</button>
         <br/> <br/>
         <div id = "greetingDiv"></div>
      </section>
      <br/> <br/> <br/>
      <hr/>
      
      <section id = "LoginSection">
         <header>
            <h2>*Login first to  access greeting </h2>
         </header>
         <input type = "text" value = "[email protected]" placeholder = "enter email" id = "txtEmail"/>
         <br/>
         
         <input type = "password" value = "pass123" placeholder = "enter password" id = "txtPwd"/>
         <br/>
         
         <input type = "button" id = "btnAuthenticate"  value = "Login"/>
         <p id = "authStatus"></p>
      </section>
   </body>
</html>