2017-08-10 131 views
1

我遇到过很多这方面的问题,但是我找不到解决方案。 的customers_controller.rb是像这样:ActiveModel :: ForbiddenAttributesError(ActiveModel :: ForbiddenAttributesError)

def create 
@customers = Customer.new(params) 
respond_to do |format| 
    if @customers.save 
    format.json { render json: @customers.to_json } 
    else 
    format.json { render json: @customers.errors, 
     status: :unprocessable_entity } 
    end 
end 
end 

class Customer < ActiveRecord::Base 
end 

模型/ customer.rb是像这样:

class Customer < ActiveRecord::Base 
end 

params = ActionController::Parameters.new({ 
    customer: { 
    first_name: "Godson", 
    last_name: "Chukwu", 
    username: "Son", 
    email:  "[email protected]" 
} 
}) 
permitted = params.require(:customer).permit(:first_name, :last_name,     :username, :email) 
permitted 
permitted.permitted? 
Customer.first.update!(permitted) 

前端侧与包/ customers.js角4代码是这样的:

import "hello_angular/polyfills"; 
import { Component, NgModule } from "@angular/core"; 
import { BrowserModule } from "@angular/platform-browser"; 
import { FormsModule } from "@angular/forms"; 
import { Http,Response, HttpModule, Headers, RequestOptions } from  "@angular/http"; 
import      "rxjs/add/operator/map"; 
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"; 

    var CustomerFormComponent = Component({ 
    selector: "shine-customer-form", 
    template: '<header class="panel-heading"> 
     <h1 class="h3"> 
     Customer 
     </h1> 
    </header> 
    <section class="panel-body"> 
     <div class="container"> 
     <form novalidate #customerRef="ngForm" (ngSubmit)="submit(customerRef.value)"> 
      <div class="row"> 
      <div class="col-md-3 form-group"> 
       <label class="sr-only" for="first-name"> 
       First Name 
       </label> 
       <input type="text" class="form-control" name="first_name" 
        placeholder="First name" ngModel #first_nameRef="ngModel"> 
      </div> 
      <div class="col-md-3 form-group"> 
       <label class="sr-only" for="last-name">Last Name</label> 
       <input type="text" class="form-control" name="last_name" 
         placeholder="Last name" ngModel #last_nameRef="ngModel"> 
      </div> 
      <div class="col-md-3 form-group"> 
       <label class="sr-only" for="username">Username</label> 
       <input type="text" class="form-control" name="username" 
         placeholder="Username" ngModel #usernameRef="ngModel"> 
      </div> 
      <div class="col-md-3 form-group"> 
       <label class="sr-only" for="email">Email</label> 
       <input type="text" class="form-control" name="email" 
         placeholder="Email" ngModel #emailRef="ngModel"> 
      </div> 
      </div> 
      <button type="submit" class="btn btn-primary">Submit</button> 
     </form> 
     <pre>{{customerRef.value | json }}<`enter code here`/pre> 
     </div> 
    </section> 
    ' 
    }).Class({ 
    constructor: [ 
     Http, 
     function(http) { 
     this.keywords = null; 
     this.customer = null; 
     this.http  = http; 
     } 
    ], 
    submit: function(customer, value){ 
    var headers = new Headers('authentication', `wsWPhTlJAmt1IcyNq1FCyivsAVhHq1iDCKRXOgOQock`); 
     var headers = new Headers({ 'Content-Type': 'application/json'}); 
     var options = new RequestOptions({ headers: headers}); 
     var body = JSON.stringify(customer); 

     //var options = new RequestOptions({headers: headers}); 

     var create = {}; 
     //var body = JSON.stringify(customer); 
     //create[customer] = value; 
     this.http.post(
     "/customers", body, options 
    ) 
     .map(function(Response){ 
     this.Response.json(); 
     }) 
     .subscribe(
     function(response) { 
      this.response.json(); 
      console.log('receive response'); 
     }, 

     function(response) { 
      window.alert(response); 
     } 
    ); 
    } 
}); 

var CustomerAppModule = NgModule({ 
imports:  [ BrowserModule, 
       FormsModule, 
       HttpModule 
      ], 
declarations: [ CustomerFormComponent ], 
bootstrap: [ CustomerFormComponent ] 
}) 
.Class({ 
constructor: function() {} 
}); 

platformBrowserDynamic().bootstrapModule(CustomerAppModule); 

下面是我的控制台输出:

16:18:20 rails.1 | app/controllers/customers_controller.rb:27:in `create' 
16:30:55 rails.1 | Started GET "/customers" for 127.0.0.1 at 2017-08-10 16:30:55 +0100 
16:30:56 rails.1 | Processing by CustomersController#index as HTML 
16:30:57 rails.1 | Customer Load (28.9ms) SELECT "customers".* FROM "customers" ORDER BY "customers"."id" ASC LIMIT $1 [["LIMIT", 1]] 
16:30:57 rails.1 | (0.3ms) BEGIN 
16:30:57 rails.1 | (0.4ms) COMMIT 
16:30:57 rails.1 | Rendering customers/index.html.erb within layouts/application 
16:30:57 rails.1 | Rendered customers/index.html.erb within layouts/application (72.5ms) 
16:30:57 rails.1 | Completed 200 OK in 786ms (Views: 329.2ms | ActiveRecord: 99.1ms) 
16:30:57 rails.1 | 
16:30:57 rails.1 | 
16:32:56 rails.1 | Started POST "/customers" for 127.0.0.1 at 2017-08-10 16:32:56 +0100 
16:32:56 rails.1 | Processing by CustomersController#create as HTML 
16:32:56 rails.1 | Parameters: {"first_name"=>"Dan", "last_name"=>"Nwa", "username"=>"Sola", "email"=>"[email protected]", "customer"=>{"first_name"=>"Dan", "last_name"=>"Nwa", "email"=>"[email protected]", "username"=>"Sola"}} 
16:32:56 rails.1 | Can't verify CSRF token authenticity. 
16:32:56 rails.1 | Completed 500 Internal Server Error in 1ms (ActiveRecord: 0.0ms) 
16:32:56 rails.1 | 
16:32:56 rails.1 | 
16:32:56 rails.1 | 
16:32:56 rails.1 | ActiveModel::ForbiddenAttributesError (ActiveModel::ForbiddenAttributesError): 
16:32:56 rails.1 | 
16:32:56 rails.1 | app/controllers/customers_controller.rb:27:in `create' 

在Firefox浏览器中预览网络请求参数是像这样:

Request 

Parameters: 

{"first_name"=>"Dan", "last_name"=>"Nwa", "username"=>"Sola", "email"=>"[email protected]", "customer"=>{"first_name"=>"Dan", "last_name"=>"Nwa", "email"=>"[email protected]", "username"=>"Sola"}} 

我在哪里得到它错了吗?

+0

您应该包括一个隐藏字段,命名为“authenticity_token”和(Rails的助手)设定的值'form_authenticity_token' – MrYoshiji

回答

1

因为您是从'Angular'提交的,所以您没有通过跨站点请求伪造(CSRF)令牌。

您可以通过多种方式解决这个问题,但有两个选择。

在你application_controller.rb添加

class ApplicationController < ActionController::Base 
    protect_from_forgery with: :null_session 
end 

或者在您的customer_controller.rb添加

skip_before_action :verify_authenticity_token 

如果你只需要跳过跨站请求伪造(CSRF),用于创建,你可以做这个。

skip_before_action :verify_authenticity_token, only: :create 
+0

在一个更好的方法(一个不回避一个很好的理由创造了一个安全检查)你可以在表单中包含auth token(助手'form_authenticity_token'返回一个有效的令牌) – MrYoshiji

+0

谢谢@MrYoshiji,我已经添加了'protect_from_forgery::null_session',** application_controller.rb **。现在,当我在** customers_controller.rb **中添加一个私有** customer_params **方法作为** create **方法的参数时,出现以下错误:'ActionController :: UnknownFormat(ActionController :: UnknownFormat): '。同时,表单现在正在向数据库提交数据。但似乎问题来自** customers_controller.rb **中的'respond_to do | format |'create方法。我将如何解决这个问题?谢谢。 –

+0

这是我的控制台日志:'19:45:55 rails.1 |参数:{“first_name”=>“Newman”,“last_name”=>“Kalu”,“username”=>“Didi”,“email”=>“[email protected]g”,“customer”=> {“ first_name“=>”Newman“,”last_name“=>”Kalu“,”email“=>”[email protected]“,”username“=>”Didi“}} 19:45:55 rail.1 |未经许可的参数:: customer 19:45:55 rail.1 | SQL(13.2ms)INSERT INTO“customers”(17.1ms)COMMIT 19:45:55 rails.1 |已完成406 35ms内不可接受(ActiveRecord:30.6ms) 19:45:55 rail.1 | ActionController :: UnknownFormat(ActionController :: UnknownFormat): '跳过了一些输出。 –

相关问题