Node JSjs快速应用程序 - 用户登录和注册错误



我对node.js和Express完全陌生。我想构建一个具有用户管理功能的应用程序。我已经咨询了风暴路径网站(https://stormpath.com/blog/build-nodejs-express-stormpath-app(以及构建并显示的应用程序,如下所示:

欢迎页面屏幕截图

当我单击"立即注册"和"立即登录"时,会发生错误:

寄存器错误屏幕截图

我完全遵循了教程,服务器.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);

索引.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框架,我想实现用户管理,谢谢。

我在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 和/forget(以及这些路由的默认视图(。我们的快速入门中对此进行了介绍,你可以在此处进行操作:https://docs.stormpath.com/nodejs/express/latest/setup.html

本教程介绍如何设置一个真正基本的快速项目,该项目有一个额外的视图,即登录用户的配置文件页面。下面是直接从教程中复制/粘贴的代码。让我知道这是否适合您。

服务器.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);

简介.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;
};

视图/首页.翡翠:

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

views/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

最新更新