다음은 Facebook API를 이용한 회원가입, 로그인 시스템입니다.
Facebook에 가입이 되어 있어야만 사용할 수 있으니 유의바랍니다.
개발자 페이스북 사이트에 접속합니다.
Facebook API를 위한 App 추가합니다.
등록할 App 이름, 본인 facebook 연락처 이메일을 등록합니다.
보안 서명 확인 후 제출합니다.
App의 대시보드 화면입니다.
본인이 등록한 App이 맞는지 확인합니다.
기본 설정에 들어간 후 앱 ID와 앱 시크릿 코드를 확인합니다.
향 후 Facebook API를 Node.js에 등록할 시 필요한 정보입니다.
카데고리는 기호에 맞게 선택해줍니다. ex) 웹 사이트
기본 설정 하단의 웹사이트 URL을 등록해야 합니다.
모두 완료되면 본인의 Facebook 계정으로 발급된 API를 확인할 수 있습니다.
모듈의 정보를 담고 있는 웹 사이트입니다.
passport 사용을 위한 환경 설정을 하여야 합니다.
facebook api를 사용하기 위한 모듈의 가이드를 따라 읽고 설치합니다.
정보들을 db에 담기 위해서는 데이터베이스에 데이터를 담을 공간을 생성해줘야 합니다.
본인의 mysql 계정에 접속합니다.
데이터베이스를 확인합니다.
데이터베이스 확인 후 사용할 데이터베이스를 선택합니다. ex) use da;
해당 데이터베이스에 table 스키마를 생성합니다.
스키마가 생성된 것을 확인합니다.
테이블을 확인합니다.
사용자 인증이 완료 되었을 때 해당 db의 table에 정보가 삽입된 것을 확인할 수 있습니다.
email의 정보를 깜빡했군요. sql 명령어를 통하여 수정을 위한 삽입을 합니다.
var express = require('express');
var session = require('express-session');
var MySQLStore = require('express-mysql-session')(session);
var bodyParser = require('body-parser');
var bkfd2Password = require("pbkdf2-password");
var passport = require('passport')
var LocalStrategy = require('passport-local').Strategy;
var FacebookStrategy = require('passport-facebook').Strategy;
var hasher = bkfd2Password();
var mysql = require('mysql');
var conn = mysql.createConnection({
host: 'localhost',
user: '사용자',
password: '비밀번호',
database: '데이터베이스'
});
conn.connect();
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({ // session 미들웨어
secret: '1234DSFs@adf1234!@#&asd',
resave: false,
saveUninitialized: true,
store: new MySQLStore({
host: 'localhost',
port: 3306,
user: '사용자',
password: '비밀번호',
database: '데이터베이스'
})
}));
app.use(passport.initialize()); // passport 초기화
app.use(passport.session()); // session을 사용
app.get('/count', function (req, res) {
if (req.session.count) {
req.session.count++;
} else {
req.session.count = 1;
}
res.send('count : ' + req.session.count);
});
app.get('/auth/logout', function (req, res) {
req.logout();
req.session.save(function () {
res.redirect('/welcome');
});
});
app.get('/welcome', function (req, res) {
if (req.user && req.user.displayName) { // passport로 부터 받은 유저 객체가 사용자 정보와 같으면
res.send(`
<h1>Hello, ${req.user.displayName}</h1>
<a href="/auth/logout">logout</a>
`);
} else {
res.send(`
<h1>Welcome</h1>
<ul>
<li><a href="/auth/login">Login</a></li>
<li><a href="/auth/register">Register</a></li>
</ul>
`);
}
});
passport.serializeUser(function (user, done) {
console.log('serializeUser', user);
done(null, user.authId);
});
passport.deserializeUser(function (id, done) {
console.log('deserializeUser', id);
var sql = 'SELECT * FROM users WHERE authId=?';
conn.query(sql, [id], function (err, results) {
if (err) {
console.log(err);
done('There is no user.');
} else {
done(null, results[0]);
}
});
// for (var i = 0; i < users.length; i++) {
// var user = users[i];
// if (user.authId === id) {
// return done(null, user);
// }
// }
// done('There is no user');
});
passport.use(new LocalStrategy( // 로컬 전략
function (username, password, done) { // 콜백함수
var uname = username;
var pwd = password;
var sql = 'SELECT * FROM users WHERE authId=?';
conn.query(sql, ['local:' + uname], function (err, results) {
console.log(results);
if (err) {
return done('There is no user.');
}
var user = results[0];
return hasher({ password: pwd, salt: user.salt }, function (err, pass, salt, hash) {
if (hash === user.password) { // 사용자가 있다면
console.log('LocalStrategy', user);
done(null, user); // 로그인 성공
} else { // 사용자가 없다면
done(null, false); // 로그인 실패
}
});
});
}
));
passport.use(new FacebookStrategy({
clientID: '어플리케이션ID',
clientSecret: '어플리케이션 비밀번호',
callbackURL: "/auth/facebook/callback",
profileFields: ['id', 'email', 'gender', 'link', 'locale',
'name', 'timezone', 'updated_time', 'verified', 'displayName']
},
function (accessToken, refreshToken, profile, done) {
console.log(profile);
var authId = 'facebook:' + profile.id;
var sql = 'SELECT * FROM users WHERE authId=?';
conn.query(sql, [authId], function(err, results){
if(results.length>0){
done(null, results[0]);
} else {
var newuser = {
'authId': authId,
'displayName': profile.displayName,
'email': profile.emails[0].value
}
var sql = 'INSERT INTO users SET ?';
conn.query(sql, newuser, function(err, results){
if(err){
console.log(err);
done('Error');
} else {
done(null, newuser);
}
})
}
});
}
));
app.post(
'/auth/login',
passport.authenticate( // 미들웨어를 받아서 인증작업을 처리
'local', // 로컬 방식
{
successRedirect: '/welcome', // 로그인 성공
failureRedirect: '/auth/login', // 로그인 실패
failureFlash: false
}
)
);
app.get('/auth/login', function (req, res) {
var output = `
<h1>Login</h1>
<form action="/auth/login" method="post">
<p>
<input type="text" name="username" placeholder="username">
</p>
<p>
<input type="password" name="password" placeholder="password">
</p>
<p>
<input type="submit">
</p>
</form>
<a href="/auth/facebook">facebook</a>
`;
res.send(output);
});
app.get(
'/auth/facebook',
passport.authenticate(
'facebook',
{ scope: 'email' }
)
);
app.get(
'/auth/facebook/callback',
passport.authenticate(
'facebook',
{
successRedirect: '/welcome',
failureRedirect: '/auth/login'
}
)
);
app.post('/auth/register', function (req, res) {
hasher({ password: req.body.password }, function (err, pass, salt, hash) {
var user = {
authId: 'local:' + req.body.username,
username: req.body.username,
password: hash,
salt: salt,
displayName: req.body.displayName
};
var sql = 'INSERT INTO users SET ?';
conn.query(sql, user, function (err, results) {
if (err) {
console.log(err);
res.status(500);
} else {
req.login(user, function (err) {
req.session.save(function () {
res.redirect('/welcome');
});
});
}
});
});
});
app.get('/auth/register', function (req, res) {
var output = `
<h1>Register</h1>
<form action="/auth/register" method="post">
<p>
<input type="text" name="username" placeholder="username">
</p>
<p>
<input type="password" name="password" placeholder="password">
</p>
<p>
<input type="text" name="displayName" placeholder="displayName">
</p>
<p>
<input type="submit">
</p>
</form>
`;
res.send(output);
});
app.listen(3003, function () {
console.log('Connected 3003 port!!!');
});