2017-04-18 2 views
0

Ich benutze Express mit Reisepass und die Pass-lokale Strategie mit mysql, um den Admin-Benutzer für eine bestimmte Seite zu authentifizieren. Das funktioniert, auf der Admin-Seite mit der Angular 2 App, habe ich eine Dropzone und ein anderes Formular, die jeweils an zwei verschiedene URLs senden. Ich bin mir nicht sicher, wie authentifiziert werden kann, dass der Benutzer beim Hochladen angemeldet ist. HierDropzone, Angular 2 authentifizieren Uploads mit Passjs

ist der Server-Code:

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); 

Ich denke, was ich tun muß, ist die Header-Informationen, die die Session-ID hat, oder Cookie und dass in Dropzone mit dem Upload senden, indem die Header dort einstellen . Aber ich bin mir nicht sicher, wie ich das machen soll.

Client-Seite 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

Sie möchten über ** Hinzufügen von Kopfzeilen in Client-Seitencode ** wissen – Aravind

Antwort

0

ich eine Antwort here gefunden. Grundsätzlich musste ich den Cookie einbeziehen, der für den Pass generiert wurde. Dies geschieht durch Aktivierung withCredentials

Dropzone

this.dropzone = new Dropzone('form#dropzone', { 
      url: "http://localhost:8080/upload-image", 
      parallelUploads: 5, 
      autoProccessQueue: true, 
      acceptedFiles: "image/*", 
      withCredentials: true // <<----- 
     }); 

Angular 2

let head = new Headers({ 'Content-Type': 'application/json' }); 
     let options = new RequestOptions({ headers: head, method: "post", withCredentials: true}); 

Einstellung withCredentials auf true ermöglicht die separate Anforderung authentifiziert werden.