Node.js Express App-用户登录&注册错误

时间:2017-02-08 14:26:51

标签: node.js express

我对node.js和Express 全新。我想用用户管理构建一个应用程序。我咨询了 stormpath 网站(https://stormpath.com/blog/build-nodejs-express-stormpath-app) 和应用程序的构建和显示如下:

The Welcome Page Screen shot

当我点击立即注册立即登录时,会出现错误:

The Register Error Screen shot

我完全按照教程, server.js 如下:

 var express = require('express');
 var stormpath = require('express-stormpath');

 var app = express();

 app.set('views', './views');
 app.set('view engine', 'jade');

 app.use(stormpath.init(app, {
 expand: {
    customData: true
   }
}));

app.get('/', stormpath.getUser, function(req, res) {
res.render('home', {
  title: 'Welcome'
   });
});

app.use('/profile',stormpath.loginRequired,require('./profile')());
app.on('stormpath.ready',function(){
console.log('Stormpath Ready');
});

app.listen(3000);

index.jade 如下所示:

html
head
title=title
link(href='//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css', 
rel='stylesheet')
body
 div.container
  div.jumbotron
    h1 Release Control System

    if user
      p Welcome, #{user.fullName}
      p
        a.small(href="profile") Edit my profile
      form(action='/logout', method='POST')
        button.btn.btn-default(type="submit") Logout
    else
      p Welcome to the release control system , please log in to get started.
      p
        a.btn.btn-primary(href="/login") Login now
      p
        span.small Don't have an account?
        span  
        a.small(href="/register") Register now

paackage.json

  {
   "name": "sampple",
   "version": "0.0.0",
   "private": true,
   "scripts": {
    "start": "node ./bin/www"
  },
   "dependencies": {
   "body-parser": "~1.16.0",
   "cookie-parser": "~1.4.3",
   "debug": "~2.6.0",
   "express": "~4.14.1",
   "jade": "~1.11.0",
   "morgan": "~1.7.0",
   "serve-favicon": "~2.3.2"
  },
   "description": "Release control",
   "main": "server.js",
   "devDependencies": {},
   "author": "",
   "license": "MIT"
  }

请告知应修改的位置以修复错误,包括按“立即登录”按钮。

任何建议都表示赞赏,因为我不熟悉node.js和Express框架,我想实现用户管理,谢谢。

1 个答案:

答案 0 :(得分:1)

我在Stormpath工作。使用快速stormpath处理您的应用程序所需的设置很少。在npm install express-stormpath添加var stormpath = require('express-stormpath');后,您只需再做两件事:

// Tell your express app to use Stormpath
app.use(stormpath.init(app, {
  // Add optional configuration settings here
  expand: { 
    customData: true
  }
}));

// Wait for Stormpath to tell you it's ready
app.on('stormpath.ready',function(){
  console.log('Stormpath Ready');
});

完成这些步骤后,您将自动获得开箱即用的/ register,/ login,/ me,/ verify和/ forgot路由(以及这些路由的默认视图)。我们的快速入门将对此进行介绍,您可以在此处查看:https://docs.stormpath.com/nodejs/express/latest/setup.html

This tutorial解释了如何设置一个真正基本的快递项目,该项目有一个额外的视图,一个用于登录用户的个人资料页面。以下是直接从教程中复制/粘贴的代码。如果这对您有用,请告诉我。

server.js:

var express = require('express'); var stormpath = require('express-stormpath');

var app = express();

app.set('views', './views'); app.set('view engine', 'jade');

app.use(stormpath.init(app, {   expand: {
    customData: true   } }));

app.get('/', stormpath.getUser, function(req, res) {   res.render('home', {
    title: 'Welcome'   }); });

app.on('stormpath.ready',function(){   console.log('Stormpath Ready'); });

app.listen(3000);

profile.js:

var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var csurf = require('csurf');
var express = require('express');
var extend = require('xtend');
var forms = require('forms');

var collectFormErrors = require('express-stormpath/lib/helpers').collectFormErrors;

// Declare the schema of our form:

var profileForm = forms.create({
  givenName: forms.fields.string({
    required: true
  }),
  surname: forms.fields.string({ required: true }),
  streetAddress: forms.fields.string(),
  city: forms.fields.string(),
  state: forms.fields.string(),
  zip: forms.fields.string()
});

// A render function that will render our form and
// provide the values of the fields, as well
// as any situation-specific locals

function renderForm(req,res,locals){
  res.render('profile', extend({
    title: 'My Profile',
    csrfToken: req.csrfToken(),
    givenName: req.user.givenName,
    surname: req.user.surname,
    streetAddress: req.user.customData.streetAddress,
    city: req.user.customData.city,
    state: req.user.customData.state,
    zip: req.user.customData.zip
  },locals||{}));
}

// Export a function which will create the
// router and return it

module.exports = function profile(){

  var router = express.Router();

  router.use(cookieParser());

  router.use(bodyParser.urlencoded({ extended: true }));

  router.use(csurf({ cookie: true }));

  // Capture all requests, the form library will negotiate
  // between GET and POST requests

  router.all('/', function(req, res) {
    profileForm.handle(req,{
      success: function(form){
        // The form library calls this success method if the
        // form is being POSTED and does not have errors

        // The express-stormpath library will populate req.user,
        // all we have to do is set the properties that we care
        // about and then cal save() on the user object:
        req.user.givenName = form.data.givenName;
        req.user.surname = form.data.surname;
        req.user.customData.streetAddress = form.data.streetAddress;
        req.user.customData.city = form.data.city;
        req.user.customData.state = form.data.state;
        req.user.customData.zip = form.data.zip;
        req.user.customData.save();
        req.user.save(function(err){
          if(err){
            if(err.developerMessage){
              console.error(err);
            }
            renderForm(req,res,{
              errors: [{
                error: err.userMessage ||
                err.message || String(err)
              }]
            });
          }else{
            renderForm(req,res,{
              saved:true
            });
          }
        });
      },
      error: function(form){
        // The form library calls this method if the form
        // has validation errors.  We will collect the errors
        // and render the form again, showing the errors
        // to the user
        renderForm(req,res,{
          errors: collectFormErrors(form)
        });
      },
      empty: function(){
        // The form library calls this method if the
        // method is GET - thus we just need to render
        // the form
        renderForm(req,res);
      }
    });
  });

  // This is an error handler for this router

  router.use(function (err, req, res, next) {
    // This handler catches errors for this router
    if (err.code === 'EBADCSRFTOKEN'){
      // The csurf library is telling us that it can't
      // find a valid token on the form
      if(req.user){
        // session token is invalid or expired.
        // render the form anyways, but tell them what happened
        renderForm(req,res,{
          errors:[{error:'Your form has expired.  Please try again.'}]
        });
      }else{
        // the user's cookies have been deleted, we dont know
        // their intention is - send them back to the home page
        res.redirect('/');
      }
    }else{
      // Let the parent app handle the error
      return next(err);
    }
  });

  return router;
};

视图/ home.jade:

html
  head
    title=title
    link(href='//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css', rel='stylesheet')
  body
    div.container
      div.jumbotron
        h1 Hello!

        if user
          p Welcome, #{user.fullName}
          p
            a.small(href="profile") Edit my profile
          form(action='/logout', method='POST')
            button.btn.btn-default(type="submit") Logout
        else
          p Welcome to my app, ready to get started?
          p
            a.btn.btn-primary(href="/login") Login now
          p
            span.small Don't have an account?
            span  
            a.small(href="/register") Register now

视图/ profile.jade:

html
  head
    title=title
    link(
      href='//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css',
      rel='stylesheet'
    )
  body
    div.container

      div.page-header
        h1 My Profile

      if errors
        each error in errors
          div.alert.alert-danger
            span #{error.error}
      if saved
        div.alert.alert-success
          span Your profile has been saved
      form.login-form.form-horizontal(method='post', role='form')
        input(name='_csrf', type='hidden', value=csrfToken)

        div.form-group
          label.col-sm-4 First Name
          div.col-sm-8
            input.form-control(
              placeholder='Your first name',
              required=true,
              name='givenName',
              type='text',
              value=givenName)
        div.form-group
          label.col-sm-4 Last Name
          div.col-sm-8
            input.form-control(placeholder='Your last name',
              required=true,
              name='surname',
              type='text',
              value=surname)
        div.form-group
          label.col-sm-4 Street address
          div.col-sm-8
            input.form-control(placeholder='e.g. 123 Sunny Ave',
              required=true,
              name='streetAddress',
              type='text',
              value=streetAddress)
        div.form-group
          label.col-sm-4 City
          div.col-sm-8
            input.form-control(placeholder='e.g. City',
              required=true,
              name='city',
              type='text',
              value=city)
        div.form-group
          label.col-sm-4 State
          div.col-sm-8
            input.form-control(placeholder='e.g. CA',
              required=true,
              name='state',
              type='text',
              value=state)
        div.form-group
          label.col-sm-4 ZIP
          div.col-sm-8
            input.form-control(placeholder='e.g. 94116',
              required=true,
              name='zip',
              type='text',
              value=zip)
        div.form-group
          div.col-sm-offset-4.col-sm-8
            button.login.btn.btn-primary(type='submit') Save
        div.pull-right
          a(href="/") Return to home page