pir*_*one 25 javascript ruby ajax ruby-on-rails httprequest
我正试图在我的网站上为用户提供"积分"或"积分"来发布有关品牌名称的推文.
我在适当的视图上有花哨的推特小部件......
<p><a href="https://twitter.com/share" class="twitter-share-button" data-text="Check Out This Awesome Website Yay" data-via="BrandName" data-hashtags="ProductName">Tweet</a>
<div id="credited"></div>
<script>window.twttr = (function (d, s, id) {
var t, js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src= "https://platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js, fjs);
return window.twttr || (t = { _e: [], ready: function (f) { t._e.push(f) } });
}(document, "script", "twitter-wjs"));
</script>
Run Code Online (Sandbox Code Playgroud)
我把JS写得很漂亮....
function creditTweet() {
$.post(
"/credit_tweet",
{},
function(result) {
var text;
if (result.status === "noop") {
text = "Thanks for sharing already!";
} else if (result.status === "ok") {
text = "5 Kredit Added";
}
$("#credited").html(text);
}
);
}
$(function() {
twttr.ready(function (twttr) {
window.twttr.events.bind('tweet', creditTweet);
});
});
Run Code Online (Sandbox Code Playgroud)
现在问题出在控制器或路由中(我发布的地方).我认为路由很好,因为POST几乎正常工作,因为这是维基百科上的错误描述 - "422 Unprocessable Entity(WebDAV; RFC 4918)请求格式正确但由于语义错误而无法遵循".
那么,你们在控制器中看到我的ruby代码有什么问题吗?
class SocialKreditController < ApplicationController
TWEET_CREDIT_AMOUNT = 5
def credit_tweet
if !signed_in?
render json: { status: :error }
elsif current_user.tweet_credited
Rails.logger.info "Not crediting #{ current_user.id }"
render json: { status: :noop }
else
Rails.logger.info "Crediting #{ current_user.id }"
current_user.update_attributes tweet_credited: true
current_user.add_points TWEET_CREDIT_AMOUNT
render json: { status: :ok }
end
end
end
Run Code Online (Sandbox Code Playgroud)
在我的routes.rb中,它非常直接,所以我怀疑这里有什么不对...
get 'social_kredit/credit_tweet'
post '/credit_tweet' => 'social_kredit#credit_tweet'
Run Code Online (Sandbox Code Playgroud)
哪里哦这个错误在哪里?我显然不知道有关HTTP请求的信息.
pir*_*one 54
我搞定了!
我加了......
skip_before_action :verify_authenticity_token
Run Code Online (Sandbox Code Playgroud)
到控制器.
检查日志并发现无法验证CSRF令牌时发现了该问题.
ihaztehcodez(他最后一次活跃是在 2016 年,所以它无助于推动他发布答案)提到该skip_before_action :verify_authenticity_token技术不是那么安全,因为你失去了伪造保护。
他们提到了最好的/安全的/“更好的做法”,这里提到了解决方案警告:无法验证 CSRF 令牌的真实性
例如
$.ajaxSetup({
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
}
});
Run Code Online (Sandbox Code Playgroud)
或者
$.ajax({ url: 'YOUR URL HERE',
type: 'POST',
beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))},
data: 'someData=' + someData,
success: function(response) {
$('#someDiv').html(response);
}
});
Run Code Online (Sandbox Code Playgroud)
或者
把它放在一个ajax请求中
headers: {
'X-Transaction': 'POST Example',
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},
Run Code Online (Sandbox Code Playgroud)