답변:
Connect 또는 Express에 대한 인증 프레임 워크를 찾고 있다면 Passport를 조사 할 가치가 있습니다. https://github.com/jaredhanson/passport
(공개 : 저는 Passport 개발자입니다)
connect-auth와 everyauth를 모두 조사한 후 Passport를 개발했습니다. 둘 다 훌륭한 모듈이지만 내 요구에 맞지 않았습니다. 나는 더 가볍고 눈에 거슬리지 않는 것을 원했습니다.
Passport는 별도의 모듈로 분류되므로 필요한 것만 사용하도록 선택할 수 있습니다 (필요한 경우에만 OAuth). Passport는 또한 응용 프로그램에 경로를 마운트하지 않으므로 인증시기 및 위치를 유연하게 결정할 수 있으며 인증 성공 또는 실패시 발생하는 상황을 제어 할 수 있습니다.
예를 들어, 양식 기반 (사용자 이름 및 비밀번호) 인증을 설정하는 2 단계 프로세스는 다음과 같습니다.
passport.use(new LocalStrategy(
function(username, password, done) {
// Find the user from your DB (MongoDB, CouchDB, other...)
User.findOne({ username: username, password: password }, function (err, user) {
done(err, user);
});
}
));
app.post('/login',
passport.authenticate('local', { failureRedirect: '/login' }),
function(req, res) {
// Authentication successful. Redirect home.
res.redirect('/');
});
Facebook, Twitter 등을 통해 인증을위한 추가 전략을 사용할 수 있습니다. 필요한 경우 사용자 지정 전략을 플러그인 할 수 있습니다.
done(null,false,{ message:'Incorrect username.' })
. 모든 매개 변수가 무엇인지 모르기 때문에 끔찍합니다.
좋은 라이브러리를 많이 찾지 못한 이유는 인증을 위해 라이브러리를 사용하는 것이 대부분 오버 엔지니어링이기 때문입니다.
당신이 찾고있는 것은 세션 바인더입니다 :)
if login and user == xxx and pwd == xxx
then store an authenticated=true into the session
if logout destroy session
그게 다야.
나는 또한 connect를 사용하고 있지만 두 가지 이유로 connect-auth를 사용하지 않습니다.
IMHO는 매우 강력하고 읽기 쉬운 양파 링 연결 아키텍처 인 connect-auth를 끊습니다. 아니-내 의견 :). 연결 작동 방식과 양파 링 아이디어에 대한 아주 좋고 짧은 기사를 여기에서 찾을 수 있습니다 .
서면으로-데이터베이스 또는 파일과 함께 기본 또는 http 로그인을 사용하려는 경우. 연결 인증이 너무 큽니다. OAuth 1.0, OAuth 2.0 & Co와 같은 것들에 더 적합합니다.
(완료되었습니다. 테스트를 위해 실행하십시오. 그러나 프로덕션 환경에서 사용하려면 https를 사용해야합니다) (그리고 REST-Principle-Compliant가 되려면 GET-Request b / c 대신 POST-Request를 사용해야합니다. 당신은 상태를 변경 :)
var connect = require('connect');
var urlparser = require('url');
var authCheck = function (req, res, next) {
url = req.urlp = urlparser.parse(req.url, true);
// ####
// Logout
if ( url.pathname == "/logout" ) {
req.session.destroy();
}
// ####
// Is User already validated?
if (req.session && req.session.auth == true) {
next(); // stop here and pass to the next onion ring of connect
return;
}
// ########
// Auth - Replace this example with your Database, Auth-File or other things
// If Database, you need a Async callback...
if ( url.pathname == "/login" &&
url.query.name == "max" &&
url.query.pwd == "herewego" ) {
req.session.auth = true;
next();
return;
}
// ####
// This user is not authorized. Stop talking to him.
res.writeHead(403);
res.end('Sorry you are not authorized.\n\nFor a login use: /login?name=max&pwd=herewego');
return;
}
var helloWorldContent = function (req, res, next) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('authorized. Walk around :) or use /logout to leave\n\nYou are currently at '+req.urlp.pathname);
}
var server = connect.createServer(
connect.logger({ format: ':method :url' }),
connect.cookieParser(),
connect.session({ secret: 'foobar' }),
connect.bodyParser(),
authCheck,
helloWorldContent
);
server.listen(3000);
나는 1 년 전에이 진술을 썼으며 현재 활성 노드 프로젝트가 없습니다. 따라서 Express에 API 변경이있을 수 있습니다. 변경해야 할 경우 의견을 추가하십시오.
연결 미들웨어에 대한 connect-auth 플러그인이 정확히 필요한 것 같습니다 : http://wiki.github.com/ciaranj/connect-auth/creating-a-form-based-strategy
express [ http://expressjs.com ]를 사용하고 있으므로 connect 플러그인은 express가 서브 클래스로 연결되어 있기 때문에 매우 잘 맞습니다.
나는 기본적으로 같은 것을 찾고있었습니다. 특히, 나는 다음을 원했다.
내가 한 일은 check_auth
인증하려는 각 경로에 인수로 전달하는 자체 미들웨어 함수 를 작성하는 것이 었습니다 . check_auth
세션을 확인하고 사용자가 로그인하지 않은 경우 다음과 같이 로그인 페이지로 리디렉션합니다.
function check_auth(req, res, next) {
// if the user isn't logged in, redirect them to a login page
if(!req.session.login) {
res.redirect("/login");
return; // the buck stops here... we do not call next(), because
// we don't want to proceed; instead we want to show a login page
}
// the user is logged in, so call next()
next();
}
그런 다음 각 경로 마다이 기능이 미들웨어로 전달되도록합니다. 예를 들면 다음과 같습니다.
app.get('/tasks', check_auth, function(req, res) {
// snip
});
마지막으로 실제로 로그인 프로세스를 처리해야합니다. 이것은 간단합니다.
app.get('/login', function(req, res) {
res.render("login", {layout:false});
});
app.post('/login', function(req, res) {
// here, I'm using mongoose.js to search for the user in mongodb
var user_query = UserModel.findOne({email:req.body.email}, function(err, user){
if(err) {
res.render("login", {layout:false, locals:{ error:err } });
return;
}
if(!user || user.password != req.body.password) {
res.render("login",
{layout:false,
locals:{ error:"Invalid login!", email:req.body.email }
}
);
} else {
// successful login; store the session info
req.session.login = req.body.email;
res.redirect("/");
}
});
});
어쨌든이 방법은 대부분 유연하고 단순하도록 설계되었습니다. 나는 그것을 향상시킬 수있는 많은 방법이 있다고 확신합니다. 당신이 있다면, 나는 당신의 의견을 매우 좋아합니다.
편집 : 이것은 간단한 예입니다. 프로덕션 시스템에서는 암호를 일반 텍스트로 저장하고 비교하지 않을 것입니다. 주석 작성자가 지적한 것처럼 암호 보안 관리에 도움이되는 lib가 있습니다.
타사 / 소셜 네트워크 로그인 통합을 원할 경우 everyauth도 살펴보십시오 .
다음은 내 프로젝트 중 하나의 기본 인증 코드입니다. 추가 인증 데이터 캐시와 함께 CouchDB에 대해 사용하지만 해당 코드를 제거했습니다.
요청 처리를 인증 방법으로 래핑하고 실패한 인증을위한 두 번째 콜백을 제공하십시오. 성공 콜백은 사용자 이름을 추가 매개 변수로 가져옵니다. 실패 콜백에서 자격 증명이 잘못되었거나 누락 된 요청을 올바르게 처리하는 것을 잊지 마십시오.
/**
* Authenticate a request against this authentication instance.
*
* @param request
* @param failureCallback
* @param successCallback
* @return
*/
Auth.prototype.authenticate = function(request, failureCallback, successCallback)
{
var requestUsername = "";
var requestPassword = "";
if (!request.headers['authorization'])
{
failureCallback();
}
else
{
var auth = this._decodeBase64(request.headers['authorization']);
if (auth)
{
requestUsername = auth.username;
requestPassword = auth.password;
}
else
{
failureCallback();
}
}
//TODO: Query your database (don't forget to do so async)
db.query( function(result)
{
if (result.username == requestUsername && result.password == requestPassword)
{
successCallback(requestUsername);
}
else
{
failureCallback();
}
});
};
/**
* Internal method for extracting username and password out of a Basic
* Authentication header field.
*
* @param headerValue
* @return
*/
Auth.prototype._decodeBase64 = function(headerValue)
{
var value;
if (value = headerValue.match("^Basic\\s([A-Za-z0-9+/=]+)$"))
{
var auth = (new Buffer(value[1] || "", "base64")).toString("ascii");
return {
username : auth.slice(0, auth.indexOf(':')),
password : auth.slice(auth.indexOf(':') + 1, auth.length)
};
}
else
{
return null;
}
};
다른 인증 방식은 고유 한 비밀번호 문제를 우회하는 Express 기반 토큰 기반 인증 모듈 인 Passwordless입니다 [1]. 구현 속도가 빠르며 너무 많은 양식이 필요하지 않으며 일반 사용자를 위해 더 나은 보안을 제공합니다 (전체 공개 : 저자입니다).
[1] : 비밀번호가 더 이상 사용되지 않습니다
몇 년이 지났고 Express 용 인증 솔루션을 소개하고 싶습니다. Lockit 이라고 합니다. GitHub 에서 프로젝트를 찾고 내 블로그 에서 짧은 소개를 찾을 수 있습니다 .
기존 솔루션과의 차이점은 무엇입니까?
require('lockit')
, lockit(app)
, 수행username
하고 password
.예제를 살펴보십시오 .
Passport를 사용하여 사용자 로그인 시스템을 구현 하고 사용자 관리 관리자 패널이있는 Drywall 이라는 프로젝트 가 있습니다. Django가 가지고 있지만 Node.js와 비슷한 기능을 갖춘 완전한 사용자 인증 및 관리 시스템을 찾고 있다면 이것이 바로 그것입니다. 사용자 인증 및 관리 시스템이 필요한 노드 앱을 구축하기에 정말 좋은 출발점이되었습니다. Passport 작동 방식에 대한 정보는 Jared Hanson의 답변 을 참조하십시오 .
다음은 노드 js 인증을위한 두 가지 인기있는 Github 라이브러리입니다.
Angular 클라이언트에 사용자 인증을 제공하는 API에 대해 mongo를 사용하는 간단한 예
app.js에서
var express = require('express');
var MongoStore = require('connect-mongo')(express);
// ...
app.use(express.cookieParser());
// obviously change db settings to suit
app.use(express.session({
secret: 'blah1234',
store: new MongoStore({
db: 'dbname',
host: 'localhost',
port: 27017
})
}));
app.use(app.router);
경로는 다음과 같습니다.
// (mongo connection stuff)
exports.login = function(req, res) {
var email = req.body.email;
// use bcrypt in production for password hashing
var password = req.body.password;
db.collection('users', function(err, collection) {
collection.findOne({'email': email, 'password': password}, function(err, user) {
if (err) {
res.send(500);
} else {
if(user !== null) {
req.session.user = user;
res.send(200);
} else {
res.send(401);
}
}
});
});
};
그런 다음 인증이 필요한 경로에서 사용자 세션을 확인할 수 있습니다.
if (!req.session.user) {
res.send(403);
}
다음은 타임 스탬프 토큰을 사용하는 새로운 인증 라이브러리입니다. 토큰은 데이터베이스에 저장하지 않고도 이메일로 보내거나 문자 메시지를 보낼 수 있습니다. 암호없는 인증 또는 2 단계 인증에 사용할 수 있습니다.
https://github.com/vote539/easy-no-password
공개 : 저는이 도서관의 개발자입니다.
Microsoft Windows 사용자 계정으로 SSO (Single Sign On)로 인증이 필요한 경우 https://github.com/jlguenego/node-expose-sspi를 시도해보십시오 .
req.sso
모든 클라이언트 사용자 정보 (로그인, 표시 이름, sid, 그룹)가 포함 된 객체를 제공합니다 .
const express = require("express");
const { sso, sspi } = require("node-expose-sspi");
sso.config.debug = false;
const app = express();
app.use(sso.auth());
app.use((req, res, next) => {
res.json({
sso: req.sso
});
});
app.listen(3000, () => console.log("Server started on port 3000"));
면책 조항 : 저는 node-expose-sspi의 저자입니다.
경량의 제로 구성 사용자 인증 모듈. 별도의 데이터베이스가 필요하지 않습니다.
https://www.npmjs.com/package/sweet-auth
다음과 같이 간단합니다.
app.get('/private-page', (req, res) => {
if (req.user.isAuthorized) {
// user is logged in! send the requested page
// you can access req.user.email
}
else {
// user not logged in. redirect to login page
}
})
omniauth
(rails) 또는 python 과 동등한 것social-auth
. PHP (및 기타 일반적인 웹 서버 언어) 사용자도 자유롭게 추가 할 수 있습니다.