【问题标题】:Laravel Upvote/Downvote system - AJAX SecurityLaravel Upvote/Downvote 系统 - AJAX 安全
【发布时间】:2013-11-28 07:01:08
【问题描述】:

我将如何在 Laravel 中创建一个安全的赞成/反对票系统,例如 reddits,甚至是无法加载虚假 ajax 请求的堆栈溢出系统。 (对不起,如果我不知道术语)。

我有 3 张桌子:

**User**
id

**Post**
id

**Vote**
id
user_id
post_id
vote (int)

我的一般想法是,当点击赞成或反对按钮时,使用 JQuery 使用具有 post_id 和投票的 POST 数据触发 AJAX,1 表示赞成,-1 表示反对)。这将由 VotesController@vote 路由选择。 vote 方法将检查用户是否经过身份验证,检查是否有来自同一用户和同一帖子的投票,如果投票存在:更改它(downvote),否则它会添加它(upvote)。

这是我的伪代码

function vote()
{
    //Checks if user is logged in
    if(Auth::check()){

        //checks if ajax request
        if (Request::ajax())
        {
                            //get my data
            $post = Input::post('post');
                            $vote = Input::post('vote');
            $user = Auth::user()->id;

            //checks if user voted
            $vote = querythatisnotyetcoded

            //if row exists 
            if($vote->count() > 0){
                //change row AKA DOWNVOTE
                Vote->vote = $vote // however you change values
            }
            else{
                //add new row AKA UPVOTE
                Vote::create([
                    'user_id' => $user,
                    'post_id' => $post,
                                'vote' => $vote
                ]);
            }
        }
        else{
            return "No Ajax Request";
        }
    }
    else{
        return "Not logged in";
    }
}   

请让我知道该逻辑是否安全。

*edit: 不知道为什么我的代码是半棕色的(已修复!)

【问题讨论】:

    标签: php jquery ajax laravel


    【解决方案1】:

    您希望它有多安全?要获得“完全”安全性,您需要通过 HTTPS 运行——但如果没有它,您可以获得一定程度的安全性。

    为防止用户伪造其他用户的投票,您需要检查用户是否已登录当前 HTTP 会话。 HTTP Session 由特定于客户端的令牌或 cookie 实现,它(通常)仅对该用户可见。

    但是,这种简单的方法无法防范精心策划的流量嗅探或中间人攻击,它们在概念上可能会捕获会话令牌并伪造请求。

    只能通过 HTTPS 或通过客户端和服务器知道但从未在它们之间发送的“共享密钥”(例如用户密码)来防御这些,也就是使用散列。这使用 HMAC 函数对密码和质询进行哈希处理,并且仅通过网络发送生成的哈希值。

    这适用于登录屏幕。

    不幸的是投票,除非您可以将密码保存在浏览器中,或者使用其他一些共享秘密来验证您的请求,否则就不是那么容易了。适用于单页 AJAX 应用程序,我不确定其他应用程序。

    【讨论】:

    • 一票赞成,一票反对。我打算专门讨论 security 问题。我假设 OP 已经可以实现 AJAX 请求。
    【解决方案2】:

    这样的事情应该可以解决问题。

    function vote()
    {    
        if (Auth::check()) {
    
            if (Request::ajax())
            {
                $post = Input::post('post');
                $vote = Input::post('vote');
                $user = Auth::user()->id;
    
                // Grab the vote if it already exists.
                $entry = Vote::where('user_id', $user)->where('post_id', $post)->first();
    
                if ($entry->count())
                {
                    $entry->vote = $vote;
                    $entry->save();
                }
                else
                {
                    $entry = new Vote;
                    $entry->user_id = $user;
                    $entry->post_id = $post;
                    $entry->save();
                }
            }
            else
            {
                return "Not an AJAX request.";
            }
        }
        else
        {
            return "User not logged in.";
        }
    }
    

    【讨论】:

    • 代码看起来不错,虽然很大程度上是从 OP 的大纲中复制而来的。但是,这如何解决安全问题以及拒绝欺骗性 AJAX 请求?
    • 只是一个简短的说明,应该是Input::get()
    • 获取 GET 数据时不只是 input::get(),我希望我的投票是 POST 数据
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-27
    • 2016-06-04
    • 2013-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多