নোড এবং এক্সপ্রেস 4 সহ বেসিক HTTP প্রমাণীকরণ


107

দেখে মনে হচ্ছে এক্সপ্রেস ভি 3 এর সাথে বেসিক এইচটিটিপি প্রমাণীকরণ বাস্তবায়ন করা তুচ্ছ ছিল:

app.use(express.basicAuth('username', 'password'));

সংস্করণ 4 (আমি 4.2 ব্যবহার করছি) basicAuthমিডওয়্যারটি সরিয়েছে , তবে আমি কিছুটা আটকেছি। আমার কাছে নিম্নলিখিত কোড রয়েছে তবে এটি ব্রাউজারের দ্বারা শংসাপত্রগুলির জন্য ব্যবহারকারীকে অনুরোধ জানায় না, যা আমি পছন্দ করি (এবং আমি পুরানো পদ্ধতিটি যা করেছি তা কল্পনা করি):

app.use(function(req, res, next) {
    var user = auth(req);

    if (user === undefined || user['name'] !== 'username' || user['pass'] !== 'password') {
        res.writeHead(401, 'Access invalid for user', {'Content-Type' : 'text/plain'});
        res.end('Invalid credentials');
    } else {
        next();
    }
});

2
নির্লজ্জ প্লাগ: আমি একটি মোটামুটি জনপ্রিয় মডিউলটি বজায় রাখি যা এটি সহজ করে তোলে এবং আপনার প্রয়োজনীয় স্ট্যান্ডার্ড বৈশিষ্ট্যগুলি রয়েছে: এক্সপ্রেস-বুনিয়াদি-
লেখক

আমি সম্প্রতি লিওনসির প্যাকেজটি তৈরি করেছি কারণ একটি সংস্থার প্রকল্পের জন্য অতি স্বল্প সময়ের মধ্যে আমাকে এটি (প্রসঙ্গ-সচেতন লেখকদের সক্ষম করা) তৈরি করতে হয়েছিল: এনএমপিজেএস
প্যাকেজ

উত্তর:


108

ভ্যানিলা জাভাস্ক্রিপ্ট (ES6) সহ সাধারণ বেসিক এথ

app.use((req, res, next) => {

  // -----------------------------------------------------------------------
  // authentication middleware

  const auth = {login: 'yourlogin', password: 'yourpassword'} // change this

  // parse login and password from headers
  const b64auth = (req.headers.authorization || '').split(' ')[1] || ''
  const [login, password] = Buffer.from(b64auth, 'base64').toString().split(':')

  // Verify login and password are set and correct
  if (login && password && login === auth.login && password === auth.password) {
    // Access granted...
    return next()
  }

  // Access denied...
  res.set('WWW-Authenticate', 'Basic realm="401"') // change this
  res.status(401).send('Authentication required.') // custom message

  // -----------------------------------------------------------------------

})

দ্রষ্টব্য: এই "মিডলওয়্যার" যে কোনও হ্যান্ডলারে ব্যবহার করা যেতে পারে। next()যুক্তিটি সরিয়ে এবং বিপরীত করুন। দেখুন 1-বিবৃতি নীচের উদাহরণে, বা সম্পাদনা ইতিহাস এই উত্তরটি করুন।

কেন?

  • req.headers.authorizationমান " Basic <base64 string>" রয়েছে তবে এটি খালিও থাকতে পারে এবং আমরা এটি ব্যর্থ হতে চাই না, তাই এর অদ্ভুত কম্বো|| ''
  • নোড জানে না atob()এবং btoa()তাইBuffer

ES6 -> ES5

constকেবলমাত্র var.. সাজানো
(x, y) => {...}কেবল একের মধ্যে function(x, y) {...}
const [login, password] = ...split()দুটি varকাজ

অনুপ্রেরণার উত্স (প্যাকেজগুলি ব্যবহার করে)


উপরেরটি একটি দুর্দান্ত সরল উদাহরণ যা আপনার খেলার মাঠের সার্ভারে অতি সংক্ষিপ্ত এবং দ্রুত ডিপ্লোয়েবল হতে পারে। তবে মন্তব্যে যেমন উল্লেখ করা হয়েছিল, পাসওয়ার্ডে কোলন অক্ষরও থাকতে পারে :। এটি b64auth থেকে সঠিকভাবে বের করতে, আপনি এটি ব্যবহার করতে পারেন।

  // parse login and password from headers
  const b64auth = (req.headers.authorization || '').split(' ')[1] || ''
  const strauth = Buffer.from(b64auth, 'base64').toString()
  const splitIndex = strauth.indexOf(':')
  const login = strauth.substring(0, splitIndex)
  const password = strauth.substring(splitIndex + 1)

  // using shorter regex by @adabru
  // const [_, login, password] = strauth.match(/(.*?):(.*)/) || []

একটি বিবৃতিতে মূল লেখক

... অন্যদিকে, আপনি যদি কখনও একটি বা খুব কম লগইন ব্যবহার করেন তবে এটি আপনার সর্বনিম্ন ন্যূনতম প্রয়োজন: (আপনার শংসাপত্রগুলি মোটেও পার্স করার প্রয়োজন নেই)

function (req, res) {
//btoa('yourlogin:yourpassword') -> "eW91cmxvZ2luOnlvdXJwYXNzd29yZA=="
//btoa('otherlogin:otherpassword') -> "b3RoZXJsb2dpbjpvdGhlcnBhc3N3b3Jk"

  // Verify credentials
  if (  req.headers.authorization !== 'Basic eW91cmxvZ2luOnlvdXJwYXNzd29yZA=='
     && req.headers.authorization !== 'Basic b3RoZXJsb2dpbjpvdGhlcnBhc3N3b3Jk')        
    return res.status(401).send('Authentication required.') // Access denied.   

  // Access granted...
  res.send('hello world')
  // or call next() if you use it as middleware (as snippet #1)
}

পিএস: আপনার কি "সুরক্ষিত" এবং "পাবলিক" পাথ দুটি দরকার? express.routerপরিবর্তে ব্যবহার বিবেচনা করুন ।

var securedRoutes = require('express').Router()

securedRoutes.use(/* auth-middleware from above */)
securedRoutes.get('path1', /* ... */) 

app.use('/secure', securedRoutes)
app.get('public', /* ... */)

// example.com/public       // no-auth
// example.com/secure/path1 // requires auth

2
প্রচুর সেরা ... :)
অনুপম বাসাক

2
ব্যবহার করবেন না .split(':')কারণ এটি কমপক্ষে একটি কোলনযুক্ত পাসওয়ার্ডগুলিতে শ্বাসরোধ করবে। এই জাতীয় পাসওয়ার্ডগুলি আরএফসি 2617 অনুসারে বৈধ ।
বিকৃতি

1
আপনি const [_, login, password] = strauth.match(/(.*?):(.*)/) || []কোলন অংশের জন্য RegExp ব্যবহার করতে পারেন ।
adabru

3
ব্যবহার !==পাসওয়ার্ডগুলি পাতার আপনি সময়জ্ঞান আক্রমণের সম্ভাবনা তুলনা। en.wikedia.org/wiki/Timing_attack নিশ্চিত করুন যে আপনি একটি ধ্রুবক সময়ের স্ট্রিং তুলনা করুন।
hraban

1
সুরক্ষা সমস্যাগুলির কারণে ব্যবহার করুন Buffer.from() // for stringsবা Buffer.alloc() // for numbersহিসাবে Buffer()হ্রাস করা হয়েছে।
মিঃ এলিয়েন

71

টি এল; ডিআর:

express.basicAuthচলে গেছে
basic-auth-connectঅবচিত
basic-authকোনো যুক্তি নেই
http-authএকটি Overkill হয়
express-basic-authআপনি যা চান তা হয়

অধিক তথ্য:

যেহেতু আপনি এক্সপ্রেস ব্যবহার করছেন তখন আপনি express-basic-authমিডওয়্যারটি ব্যবহার করতে পারেন ।

দস্তাবেজগুলি দেখুন:

উদাহরণ:

const app = require('express')();
const basicAuth = require('express-basic-auth');
 
app.use(basicAuth({
    users: { admin: 'supersecret123' },
    challenge: true // <--- needed to actually show the login dialog!
}));

17
challenge: trueবিকল্প সম্পর্কে সন্ধান করার জন্য আমাকে কিছুটা সময়
নিলো

1
@ ভিটালিজুরিয়ান ভাল পয়েন্ট - আমি এটি উত্তরে যুক্ত করেছি। এটা ইশারা জন্য ধন্যবাদ।
আরএসপি

4
@rsp আপনি কীভাবে এটি শুধুমাত্র নির্দিষ্ট রুটে প্রয়োগ করতে জানেন?
জর্জি এল হার্নান্দেজ

আপনি যদি অন্যান্য নির্ভরতা যুক্ত করতে না চান তবে এক লাইনে হাত দিয়ে মৌলিক রচনাটি লেখা খুব সহজ ...
কিওয়ার্টি

ক্লায়েন্ট ইউআরএল দেখতে কেমন হবে?
জিজিইভ

57

অনেক মিডলওয়্যারকে ভি 4-তে এক্সপ্রেস কোর থেকে বের করে এনে পৃথক মডিউল স্থাপন করা হয়েছিল। প্রাথমিক লেখক মডিউলটি এখানে: https://github.com/expressjs/basic-auth-connect

আপনার উদাহরণটি কেবল এটিতে পরিবর্তন করতে হবে:

var basicAuth = require('basic-auth-connect');
app.use(basicAuth('username', 'password'));

19
এই মডিউলটি
অবহেলিত

3
^^ নিখুঁতভাবে অননুমোদিত হিসাবে একেবারে অসন্তুষ্ট। মিডলওয়্যার হিসাবে ব্যবহারের শূন্য উদাহরণ, এটি সম্ভবত এটির পক্ষে ভাল তবে অনুরোধটি অনুপলব্ধ। তারা যে উদাহরণ দেয় তা সাধারণতার জন্য দুর্দান্ত তবে ব্যবহারের তথ্যের জন্য নয়।
ওয়াইলি কুলিক

হ্যাঁ এটিকে অবমূল্য
লৌর ২

1
আমি এই উত্তরেbasic-auth লাইব্রেরিটি কীভাবে ব্যবহার করব তা বর্ণনা করেছি
লোরর

কোডটিতে পাসওয়ার্ডটি পাসওয়ার্ডে রাখার ভিত্তিতে কীভাবে একটি সম্পূর্ণ মডিউল বিদ্যমান ? কমপক্ষে বেস 64 এর সাথে তুলনা করে এটি অস্পষ্ট করা সামান্য ভাল বলে মনে হয়।
ব্যবহারকারী 1944491

33

আমি basicAuthউত্তরটি খুঁজে পেতে মূলটির জন্য কোডটি ব্যবহার করেছি :

app.use(function(req, res, next) {
    var user = auth(req);

    if (user === undefined || user['name'] !== 'username' || user['pass'] !== 'password') {
        res.statusCode = 401;
        res.setHeader('WWW-Authenticate', 'Basic realm="MyRealmName"');
        res.end('Unauthorized');
    } else {
        next();
    }
});

10
এই মডিউলটিকে অবহেলিত হিসাবে বিবেচনা করা হয়েছে, পরিবর্তে jshttp / বেসিক-লেখার ব্যবহার করুন (একই এপিআই তাই উত্তর এখনও প্রযোজ্য)
মাইকেল

32

আমি এক্সপ্রেস 4.0.০-তে পরিবর্তিত হয়েছি http-auth এর সাথে বেসিক প্রমাণীকরণ , কোডটি হ'ল:

var auth = require('http-auth');

var basic = auth.basic({
        realm: "Web."
    }, function (username, password, callback) { // Custom authentication method.
        callback(username === "userName" && password === "password");
    }
);

app.get('/the_url', auth.connect(basic), routes.theRoute);

1
এটি আক্ষরিকভাবে প্লাগ এবং প্লে। Exellent।
সিডোনাল্ডসন

20

এটি করার জন্য একাধিক মডিউল রয়েছে বলে মনে হচ্ছে, কিছু অবমূল্যায়ন করা হয়েছে।

এটি সক্রিয় দেখায়:
https://github.com/jshttp/basic-auth

এখানে একটি ব্যবহার উদাহরণ:

// auth.js

var auth = require('basic-auth');

var admins = {
  'art@vandelay-ind.org': { password: 'pa$$w0rd!' },
};


module.exports = function(req, res, next) {

  var user = auth(req);
  if (!user || !admins[user.name] || admins[user.name].password !== user.pass) {
    res.set('WWW-Authenticate', 'Basic realm="example"');
    return res.status(401).send();
  }
  return next();
};




// app.js

var auth = require('./auth');
var express = require('express');

var app = express();

// ... some not authenticated middlewares

app.use(auth);

// ... some authenticated middlewares

আপনি authমিডলওয়্যারটি সঠিক জায়গায় রেখেছেন তা নিশ্চিত করুন , এর আগে কোনও মিডলওয়্যার প্রমাণীকরণ হবে না।


আমি আসলে 'বেসিক-লেখক-সংযোগ' এর পক্ষে, নামটি খারাপ তবে কার্যকারিতা অনুসারে এটি 'বেসিক-লেখার' চেয়ে ভাল is সমস্ত উত্তরসূচকগুলি হ'ল পার্স অনুমোদনের শিরোনাম। আপনাকে এখনও implementপ্রোটোকলটি নিজের কাছে রাখতে হবে (ওরফে সঠিক শিরোনাম প্রেরণ করুন)
এফডিআইএম

পারফেক্ট! এই জন্য আপনাকে ধন্যবাদ. এটি কাজ করেছে এবং সুন্দরভাবে সবকিছু ব্যাখ্যা করেছে।
তানিয়া রাসিয়া

আমি এটি চেষ্টা করেছিলাম তবে এটি আমাকে ক্রমাগত লুপের মাধ্যমে লগইন করতে বলে asking
jdog

6

আমরা কোনও মডিউলের প্রয়োজন ছাড়াই বেসিক অনুমোদনের প্রয়োগ করতে পারি

//1.
var http = require('http');

//2.
var credentials = {
    userName: "vikas kohli",
    password: "vikas123"
};
var realm = 'Basic Authentication';

//3.
function authenticationStatus(resp) {
    resp.writeHead(401, { 'WWW-Authenticate': 'Basic realm="' + realm + '"' });
    resp.end('Authorization is needed');

};

//4.
var server = http.createServer(function (request, response) {
    var authentication, loginInfo;

    //5.
    if (!request.headers.authorization) {
        authenticationStatus (response);
        return;
    }

    //6.
    authentication = request.headers.authorization.replace(/^Basic/, '');

    //7.
    authentication = (new Buffer(authentication, 'base64')).toString('utf8');

    //8.
    loginInfo = authentication.split(':');

    //9.
    if (loginInfo[0] === credentials.userName && loginInfo[1] === credentials.password) {
        response.end('Great You are Authenticated...');
         // now you call url by commenting the above line and pass the next() function
    }else{

    authenticationStatus (response);

}

});
 server.listen(5050);

সূত্র: - http://www.dotnetcurry.com/nodejs/1231/basic-authentication- using - nodejs


1

এক্সপ্রেস এই কার্যকারিতাটি সরিয়ে নিয়েছে এবং এখন আপনাকে বেসিক-লেখক লাইব্রেরিটি ব্যবহার করার পরামর্শ দেয় ।

কীভাবে ব্যবহার করবেন তার উদাহরণ এখানে:

var http = require('http')
var auth = require('basic-auth')

// Create server
var server = http.createServer(function (req, res) {
  var credentials = auth(req)

  if (!credentials || credentials.name !== 'aladdin' || credentials.pass !== 'opensesame') {
    res.statusCode = 401
    res.setHeader('WWW-Authenticate', 'Basic realm="example"')
    res.end('Access denied')
  } else {
    res.end('Access granted')
  }
})

// Listen
server.listen(3000)

এই রুটে একটি অনুরোধ প্রেরণ করতে আপনাকে প্রাথমিক অনুমোদনের জন্য বিন্যাস করা কোনও অনুমোদন শিরোনাম অন্তর্ভুক্ত করতে হবে ।

প্রথমে কার্ল অনুরোধ প্রেরণ করাতে আপনাকে অবশ্যই বেস 64 এর এনকোডিং নিতে হবে name:passবা এই ক্ষেত্রে aladdin:opensesameযা সমানYWxhZGRpbjpvcGVuc2VzYW1l

আপনার কার্ল অনুরোধটি এর পরে দেখতে পাবেন:

 curl -H "Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l" http://localhost:3000/

0
function auth (req, res, next) {
  console.log(req.headers);
  var authHeader = req.headers.authorization;
  if (!authHeader) {
      var err = new Error('You are not authenticated!');
      res.setHeader('WWW-Authenticate', 'Basic');
      err.status = 401;
      next(err);
      return;
  }
  var auth = new Buffer.from(authHeader.split(' ')[1], 'base64').toString().split(':');
  var user = auth[0];
  var pass = auth[1];
  if (user == 'admin' && pass == 'password') {
      next(); // authorized
  } else {
      var err = new Error('You are not authenticated!');
      res.setHeader('WWW-Authenticate', 'Basic');      
      err.status = 401;
      next(err);
  }
}
app.use(auth);

আশা করি এটি সমস্যার সমাধান করবে তবে দয়া করে এটি দিয়ে আপনার কোডের ব্যাখ্যা যুক্ত করুন যাতে ব্যবহারকারী সঠিকভাবে বুঝতে পারে যা সে / সে সত্যই চায়।
জামিল প্যাটেল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.