我使用带护照的Express和带有mysql的护照本地策略来验证特定页面的管理员用户。哪个有效,在带有Angular 2应用程序的管理页面中,我有一个Dropzone和另一个表单,每个表单都提交给两个不同的URL。我不确定如何在上传时验证用户是否已登录。
这是服务器代码:
const express = require('express');
const path = require('path');
const fs = require('fs');
const I = require('./server/image');
const marked = require('marked');
const session = require('express-session');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const passport = require('passport');
const flash = require('connect-flash');
const formidable = require('formidable');
const mysql = require('mysql');
const LocalStrategy = require('passport-local').Strategy;
// const valid = require('express-validator');
isLoggedIn = (req, res, next) => {
if (req.isAuthenticated()){
console.log("logged in");
return next();
}
console.log("not logged in");
res.redirect('/');
};
var connection = mysql.createConnection({
'host': 'localhost',
'user': 'localhost',
'password': 'localhost'
});
connection.query('USE passport');
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
connection.query("SELECT * FROM users WHERE id = ? ", [id], function(err, rows) {
done(err, rows[0]);
});
});
passport.use('local-login', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField: 'username',
passwordField: 'password',
passReqToCallback: true // allows us to pass back the entire request to the callback
}, function(req, username, password, done) { // callback with email and password from our form
connection.query("SELECT * FROM users WHERE username = ?", [username], function(err, rows) {
if (err)
return done(err);
if (!rows.length) {
return done(null, false, req.flash('loginMessage', 'No user found.')); // req.flash is the way to set flashdata using connect-flash
}
// if the user is found but the password is wrong
// if (!bcrypt.compareSync(password, rows[0].password))
if(password != rows[0].password)
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); // create the loginMessage and save it to session as flashdata
// all is well, return successful user
return done(null, rows[0]);
});
}));
var image = new I();
var app = express();
app.use(cookieParser());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
app.use(session({
secret: 'testingsecret',
resave: true,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use('/', express.static(path.join(__dirname, 'front-end/dist')));
app.use('/admin', isLoggedIn, express.static(path.join(__dirname, 'admin/dist')))
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', 'http://localhost:4200');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Cache-Control');
next();
});
app.use("/bc", express.static(path.join(__dirname, "bower_components")));
app.use("/i", express.static(path.join(__dirname, "image")));
app.get('/admin', isLoggedIn, (req, res) => {
res.sendFile(path.join(__dirname, 'admin/dist/index.html'));
});
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'front-end/dist/index.html'));
});
app.get('/login', (req, res) => {
res.sendFile(path.join(__dirname, 'login.html'));
});
app.post('/login', passport.authenticate('local-login', {
successRedirect: '/admin',
failureRedirect: '/login',
failureFlash: true
}), (req, res) => {
if (req.body.remember) {
req.session.cookie.maxAge = 1000 * 60 * 3;
} else {
req.session.cookie.expires = false;
}
res.redirect('/');
});
app.get('/logout', (req, res) => {
req.logout();
res.redirect('/');
});
findUnique = (file, pth) => {
var post = file.match(/.\w+$/)[0];
var pre = file.replace(post, '');
pre = pre +"(";
post = ")"+post;
for(var i=1; i<5000; i++){
if(!fs.existsSync(path.join(pth, pre+i+post))){
return pre+i+post;
}
}
};
app.post('/upload-image', isLoggedIn, (req, res) => {
var form = formidable.IncomingForm();
form.uploadDir = path.join(__dirname, "image");
var fileIn;
form.parse(req, (err, fields, files) => {
fileIn = files;
});
form.on('end', () => {
var name = fileIn.file.name;
var pth = fileIn.file.path;
var pthNew = path.dirname(pth);
if(fs.existsSync(path.join(pthNew, name))){
name = findUnique(name, pthNew);
}
fs.rename(pth, path.join(pthNew, name));
res.send({filename: name});
});
});
app.listen(8080);
我认为我需要做的是获取具有会话ID或cookie的标头信息,并通过在其中设置标头将其与Dropzone中的上传一起发送。但我不知道该怎么做。
客户端Angular 2:
import { Component, AfterContentInit } from '@angular/core';
import { Http, Headers, RequestOptions } from '@angular/http';
import { ImageService } from './image.service';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
declare var Dropzone: any;
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements AfterContentInit {
constructor(private image: ImageService, private http: Http) {}
ngAfterContentInit(): void {
this.dropzone = new Dropzone('form#dropzone', {
url: "http://localhost:8080/upload-image",
parallelUploads: 5,
autoProccessQueue: true,
acceptedFiles: "image/*"
});
this.dropzone.on('success', (file, res) => {
console.log(res.filename);
});
}
}
答案 0 :(得分:0)
我找到了答案here。基本上我需要包括为护照生成的cookie。这是通过启用withCredentials
this.dropzone = new Dropzone('form#dropzone', {
url: "http://localhost:8080/upload-image",
parallelUploads: 5,
autoProccessQueue: true,
acceptedFiles: "image/*",
withCredentials: true // <<-----
});
let head = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: head, method: "post", withCredentials: true});
将withCredentials
设置为true可以对单独的请求进行身份验证。