使用express+passport实现的Nodejs完整新浪微博 oauth例子

使用express+passport实现的Nodejs完整新浪微博 oauth例子

使用express+passport实现的一个完整新浪微博oauth例子,可以在hackthon时实现快速实现新浪微博登录功能(也可快速添加其他oauth provider)

主要功能:

  • 本地email+password登录
  • 直接新浪weibo登录
  • 本地登录后绑定新浪微博账号
  • 解除绑定功能

依赖:

  • Express 4.0
  • Passportjs + passport-weibo
  • Mongodb(Mongoose)

地址: node-auth-weibo


3 回复

好的,我将提供一个简化的示例来展示如何使用 expresspassport 实现一个完整的微博 OAuth 登录。这个示例包括基本的用户认证、微博登录以及绑定/解绑功能。

示例代码

首先,确保你已经安装了必要的依赖:

npm install express mongoose passport passport-weibo

接下来,创建 app.js 文件,并配置 express, mongoose, passport 以及 passport-weibo

const express = require('express');
const session = require('express-session');
const MongoStore = require('connect-mongo')(session);
const mongoose = require('mongoose');
const passport = require('passport');
const WeiboStrategy = require('passport-weibo').Strategy;

const app = express();

// MongoDB 连接
mongoose.connect('mongodb://localhost/nodeauth', { useNewUrlParser: true, useUnifiedTopology: true });

// 用户模型
const User = mongoose.model('User', new mongoose.Schema({ username: String, password: String, weiboId: String }));

// Passport 初始化
passport.use(new WeiboStrategy({
    consumerKey: 'YOUR_WEIBO_CONSUMER_KEY',
    consumerSecret: 'YOUR_WEIBO_CONSUMER_SECRET',
    callbackURL: "http://localhost:3000/auth/weibo/callback"
  },
  function(token, tokenSecret, profile, cb) {
    User.findOne({ weiboId: profile.id }, function (err, user) {
      if (err) return cb(err);
      if (!user) {
        user = new User({
          username: profile.username,
          weiboId: profile.id
        });
        user.save(function (err) {
          if (err) return cb(err);
          return cb(null, user);
        });
      } else {
        return cb(null, user);
      }
    });
  }
));

passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  User.findById(id, function(err, user) {
    done(err, user);
  });
});

// Express 配置
app.use(session({
  secret: 'secret',
  resave: false,
  saveUninitialized: false,
  store: new MongoStore({ mongooseConnection: mongoose.connection })
}));

app.use(passport.initialize());
app.use(passport.session());

app.get('/', (req, res) => {
  res.send(req.user ? `Hello ${req.user.username}` : 'Welcome to the site!');
});

app.get('/login', (req, res) => {
  res.send(`
    <form action="/auth/local" method="post">
      Username: <input type="text" name="username"><br>
      Password: <input type="password" name="password"><br>
      <button type="submit">Login</button>
    </form>
  `);
});

app.post('/auth/local', (req, res, next) => {
  // 简化处理,实际应用中需要验证用户名和密码
  req.login({ username: req.body.username }, err => err ? next(err) : res.redirect('/'));
});

app.get('/auth/weibo', passport.authenticate('weibo'));

app.get('/auth/weibo/callback',
  passport.authenticate('weibo', { failureRedirect: '/login' }),
  function(req, res) {
    res.redirect('/');
  });

app.listen(3000, () => console.log('Server running on port 3000'));

解释

  1. 依赖安装:我们安装了 express, mongoose, passport, passport-weibo
  2. MongoDB 连接:连接到 MongoDB 数据库。
  3. 用户模型:定义了一个简单的用户模型,包含用户名和微博 ID。
  4. Passport 配置:配置了微博策略,用于处理微博登录。
  5. Express 配置:配置了会话存储和路由。
  6. 路由:定义了基本的登录、微博登录和回调处理。

这个示例展示了如何使用 expresspassport 实现微博 OAuth 登录的基本流程。你可以在此基础上扩展更多的功能,如密码登录、用户绑定和解绑等。


非常感谢!

以下是使用 expresspassport 实现的 Node.js 完整新浪微博 OAuth 示例。这个例子展示了如何实现本地登录、新浪微博登录、本地账户与新浪微博账户绑定及解绑等功能。

1. 初始化项目

首先安装必要的依赖:

npm init -y
npm install express passport passport-weibo connect-flash mongoose body-parser express-session

2. 配置文件

创建一个 .env 文件来存储环境变量:

WEIBO_CLIENT_ID=your_weibo_client_id
WEIBO_CLIENT_SECRET=your_weibo_client_secret
MONGO_URI=mongodb://localhost:27017/auth-example

使用 dotenv 来加载这些变量:

require('dotenv').config();

3. Express 和 Passport 配置

创建一个 app.js 文件,并配置 expresspassport

const express = require('express');
const session = require('express-session');
const passport = require('passport');
const WeiboStrategy = require('passport-weibo-oauth2').Strategy;
const flash = require('connect-flash');
const mongoose = require('mongoose');

const app = express();

// MongoDB connection
mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true });

// Session configuration
app.use(session({
    secret: 'secret',
    resave: false,
    saveUninitialized: false
}));

// Passport initialization
app.use(passport.initialize());
app.use(passport.session());

// Flash messages
app.use(flash());

// Body parser
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// Passport strategy for Weibo
passport.use(new WeiboStrategy({
    clientID: process.env.WEIBO_CLIENT_ID,
    clientSecret: process.env.WEIBO_CLIENT_SECRET,
    callbackURL: "/auth/weibo/callback"
}, (accessToken, refreshToken, profile, done) => {
    // Here you would typically save the profile and accessToken to your database
    return done(null, profile);
}));

// Serialize and deserialize user
passport.serializeUser((user, done) => {
    done(null, user);
});

passport.deserializeUser((user, done) => {
    done(null, user);
});

// Routes
app.get('/auth/weibo', passport.authenticate('weibo'));

app.get('/auth/weibo/callback', 
    passport.authenticate('weibo', { failureRedirect: '/login' }),
    (req, res) => {
        res.redirect('/');
    }
);

app.listen(3000, () => console.log('Server started on port 3000'));

4. 模型定义

定义用户模型:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const UserSchema = new Schema({
    email: String,
    password: String,
    weiboId: String,
    weiboUsername: String
});

module.exports = mongoose.model('User', UserSchema);

5. 绑定和解绑功能

你可以通过增加 API 端点来处理绑定和解绑逻辑。例如:

app.post('/bind-weibo', (req, res) => {
    const userId = req.user._id;
    const weiboId = req.body.weiboId;
    const weiboUsername = req.body.weiboUsername;

    User.findByIdAndUpdate(userId, {
        weiboId,
        weiboUsername
    }, (err, user) => {
        if (err) return res.status(500).send(err);
        res.send(user);
    });
});

app.post('/unbind-weibo', (req, res) => {
    const userId = req.user._id;

    User.findByIdAndUpdate(userId, {
        weiboId: null,
        weiboUsername: null
    }, (err, user) => {
        if (err) return res.status(500).send(err);
        res.send(user);
    });
});

6. 安全性注意事项

确保你的应用在生产环境中使用 HTTPS,保护好你的密钥和敏感数据。此外,确保正确地处理错误和异常情况。

完整的代码可以在这个仓库中找到:node-auth-weibo

这个例子提供了一个基础框架,你可以根据需要进行扩展和修改。

回到顶部