Django增加QQ第三方登錄

準(zhǔn)備工作_OAuth2.0

接入QQ登錄前妖啥,網(wǎng)站需首先進(jìn)行申請(qǐng)陨晶,獲得對(duì)應(yīng)的appid與appkey芝硬,以保證后續(xù)流程中可正確對(duì)網(wǎng)站與用戶進(jìn)行驗(yàn)證與授權(quán)蚜点。


QQ-API調(diào)用步驟

在開發(fā)的過程中,發(fā)現(xiàn)獲取不到QQ號(hào)拌阴,只能獲取一個(gè)OpenID的東西绍绘。最后采取存儲(chǔ)這個(gè)OpenID并綁定對(duì)應(yīng)賬號(hào)的方式。
所以需要?jiǎng)?chuàng)建對(duì)應(yīng)的模型皮官,即創(chuàng)建一個(gè)應(yīng)用管理第三方登錄脯倒。

QQ登錄功能開發(fā)流程如下圖:


QQ第三方登錄

第1步实辑、QQ互聯(lián)注冊(cè)網(wǎng)站應(yīng)用
打開QQ互聯(lián)捺氢,進(jìn)入管理中心。注冊(cè)一下應(yīng)用開發(fā)者剪撬,并添加網(wǎng)站應(yīng)用摄乒,獲得對(duì)應(yīng)的appid與appkey。

APP ID和KEY

申請(qǐng)appid和appkey的用途
appid:應(yīng)用的唯一標(biāo)識(shí)。在OAuth2.0認(rèn)證過程中馍佑,appid的值即為oauth_consumer_key的值斋否。
appkey:appid對(duì)應(yīng)的密鑰,訪問用戶資源時(shí)用來驗(yàn)證應(yīng)用的合法性拭荤。在OAuth2.0認(rèn)證過程中茵臭,appkey的值即為oauth_consumer_secret的值。

應(yīng)用申請(qǐng)
應(yīng)用接口

理解回調(diào)地址需要了解一下OAuth協(xié)議舅世。
在你的網(wǎng)站頁面里面旦委,打開授權(quán)頁面(這個(gè)授權(quán)頁面不是回調(diào)地址)。在授權(quán)頁面里面雏亚,登錄QQ并確認(rèn)授權(quán)缨硝。
授權(quán)之后,會(huì)得到一個(gè)授權(quán)碼罢低〔楸纾回調(diào)地址就是用于接收這個(gè)授權(quán)碼。
授權(quán)碼以GET的方式返回网持,例如 http://www.junxi.site/web/oauth/qq/check/?code=xxxxxxxxxxxxx
通過這種方式宜岛,可以獲取授權(quán)碼,所以需要提供一個(gè)地址功舀。這個(gè)地址先寫一個(gè)暫時(shí)沒有的地址谬返,后面開發(fā)的時(shí)候,再給這個(gè)地址寫對(duì)應(yīng)的響應(yīng)方法日杈。

第2步遣铝、放置QQ按鈕
這個(gè)QQ按鈕是提供QQ登錄的入口。從騰訊提供的QQ按鈕下載放到你的登錄頁面即可莉擒。

QQ登錄按鈕

不用看幫助文檔里面的什么前端代碼酿炸。這些用不上,只需要加一個(gè)固定的訪問鏈接涨冀,再重定向即可填硕。
前端頁面此處的代碼如下:

<div>
    <span>其他登錄方式:</span>
    <a href="{% url 'qq_login' %}">
        ![](/static/images/connect_qq.png)
    </a>
</div>

qq_login鏈接在下面第3步創(chuàng)建web應(yīng)用里面設(shè)置。

第3步鹿鳖、創(chuàng)建web應(yīng)用
怎么創(chuàng)建應(yīng)用就不細(xì)說了扁眯,這是基本功。這里我已經(jīng)創(chuàng)建了一個(gè)名稱為web的django app應(yīng)用翅帜。
創(chuàng)建完成之后姻檀,打開models.py文件,編寫模型:

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
__author__ = 'junxi'

import sys
reload(sys)
sys.setdefaultencoding('utf8')

class OAuthQQ(models.Model):
    """QQ and User Bind"""
    user = models.ForeignKey(UserProfile)   # 關(guān)聯(lián)用戶信息表
    qq_openid = models.CharField(max_length=64)   # QQ的關(guān)聯(lián)OpenID
    
    # def __str__(self):
    #    return self.user

該模型用于存儲(chǔ)QQ登錄返回的OpenID值涝滴。這個(gè)OpenID值是用QQ號(hào)一一對(duì)應(yīng)绣版。騰訊不給得到真實(shí)QQ號(hào)可能是出于保護(hù)隱私的考慮胶台。

在總的urls路由中,加入這個(gè)應(yīng)用路由杂抽。(總路由在和工程名一樣的文件夾中的urls.py文件诈唬。這種方式對(duì)urls管理比較清晰)

from django.conf.urls import url, include
from django.contrib import admin
import web.urls
import web.views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^web/', include(web.urls)),
]

路由控制根據(jù)自己的工程自己寫即可。

打開web應(yīng)用目錄下urls.py文件缩麸,先寫一下需要哪些鏈接地址:

from django.conf.urls import url
from .views import *

urlpatterns = [
    url(r'^oauth/qq/login/$', login, name='qq_login'),
    url(r'^oauth/qq/check/$', login, name='qq_check'),
    url(r'^oauth/bind/account/$', login, name='bind_account'),
]

qq_login和qq_check铸磅,分別是打開授權(quán)頁面和回調(diào)地址。
bind_account是綁定用戶的頁面杭朱。
大致思路是授權(quán)之后愚屁,得到OpenID。判斷這個(gè)OpenID是否存在數(shù)據(jù)庫中痕檬。若存在霎槐,則直接登錄對(duì)應(yīng)的用戶即可;若不存在梦谜,則打開這個(gè)綁定郵箱頁面丘跌,綁定對(duì)應(yīng)的用戶。

第4步唁桩、開發(fā)OAuth登錄功能
為了管理好OAuth闭树,在web應(yīng)用的文件夾下創(chuàng)建oauth_client.py文件。把相關(guān)的OAuth操作方法集成在一起荒澡。編輯oauth_client.py文件:

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
__author__ = 'junxi'

import json
import urllib, urllib2, urlparse


class OAuthQQ:
    def __init__(self, client_id, client_key, redirect_uri):
        self.client_id = client_id
        self.client_key = client_key
        self.redirect_uri = redirect_uri

    def get_auth_url(self):
        """獲取授權(quán)頁面的網(wǎng)址"""
        params = {'client_id': self.client_id,
                  'response_type': 'code',
                  'redirect_uri': self.redirect_uri,
                  'scope': 'get_user_info',
                  'state': 1}
        url = 'https://graph.qq.com/oauth2.0/authorize?%s' % urllib.urlencode(params)
        return url

創(chuàng)建一個(gè)類报辱,需要申請(qǐng)QQ登錄的APP_ID、APP_KEY和回調(diào)地址单山。這些都是固定的碍现,我把這幾個(gè)常量放入到settings.py中。settings.py添加如下常量米奸,具體的值請(qǐng)?jiān)谀愕纳暾?qǐng)頁面查找(這里還需要提一下昼接,本地調(diào)試的方法。因?yàn)槭跈?quán)之后是調(diào)整到部署之后的網(wǎng)站上悴晰,而部署的網(wǎng)站還沒開發(fā)響應(yīng)的代碼慢睡,無法響應(yīng)對(duì)應(yīng)的地址。這里我是本地測(cè)試環(huán)境铡溪,強(qiáng)制綁定Hosts域名文件解析):

修改Hosts文件
# OAuth設(shè)置
QQ_APP_ID = 'XXXXXX'
QQ_KEY = 'XXXXXX'
QQ_RECALL_URL = 'http://www.junxi.site/web/oauth/qq/check'

回到OAuthQQ類漂辐,現(xiàn)里面有個(gè)get_auth_url方法。該方法是獲取打開授權(quán)頁面的鏈接地址棕硫。(可參考官方幫助髓涯,寫得不夠清晰)

接著,在編輯web應(yīng)用的views.py文件饲帅,加入qq_login對(duì)應(yīng)的響應(yīng)方法:

from django.shortcuts import HttpResponseRedirect
from django.conf import settings
from oauth_client import OAuthQQ
 

def qq_login(request):
    oauth_qq = OAuthQQ(settings.QQ_APP_ID, settings.QQ_KEY, settings.QQ_RECALL_URL)
 
    #獲取 得到Authorization Code的地址
    url = oauth_qq.get_auth_url()
    #重定向到授權(quán)頁面
    return HttpResponseRedirect(url)

到這里為止复凳,就完成了點(diǎn)擊QQ登錄按鈕瘤泪,跳轉(zhuǎn)到授權(quán)頁面灶泵。
登錄授權(quán)之后育八,授權(quán)頁面會(huì)自動(dòng)跳轉(zhuǎn)到我們?cè)O(shè)置的回調(diào)地址。例如 http://www.junxi.site/web/oauth/qq/check?code=xxxxxxxxxxxxx
我們可以獲取這個(gè)地址上面的GET參數(shù)赦邻。先假設(shè)我們可以順利獲取到髓棋,繼續(xù)完善OAuthQQ類。拿到這個(gè)授權(quán)碼之后惶洲,需要用該碼獲取騰訊的access_token通行令牌按声。

打開oauth_client.py文件,在OAuthQQ類添加如下方法:

    def get_access_token(self, code):
        """根據(jù)code獲取access_token"""
        params = {'grant_type': 'authorization_code',
                  'client_id': self.client_id,
                  'client_secret': self.client_key,
                  'code': code,
                  'redirect_uri': self.redirect_uri}    # 回調(diào)地址
        url = 'https://graph.qq.com/oauth2.0/token?%s' % urllib.urlencode(params)

        # 訪問該網(wǎng)址恬吕,獲取access_token
        response = urllib2.urlopen(url).read()
        result = urlparse.parse_qs(response, True)

        access_token = str(result['access_token'][0])
        self.access_token = access_token
        return access_token

該方法使用了urllib2签则,在服務(wù)器后臺(tái)訪問對(duì)應(yīng)的鏈接,獲取access_token铐料,并返回該值渐裂。因?yàn)槲液罄m(xù)不需要用access_token做其他動(dòng)作,直接一次性獲取QQ昵稱和OpenID钠惩。所以不用記錄這個(gè)通行令牌的有效期柒凉。

得到這個(gè)access_token之后,就可以做其他事了篓跛。首先需要獲取授權(quán)用戶的OpenID膝捞,因?yàn)轵v訊不允許獲取QQ號(hào)。只好退而求次愧沟,獲取并保存OpenID蔬咬。可參考官方文檔沐寺。
繼續(xù)給這個(gè)OAuthQQ添加獲取OpenID的方法和使用OpenID獲取QQ基本信息的方法:

    def get_open_id(self):
        """獲取QQ的OpenID"""
        params = {'access_token': self.access_token}
        url = 'https://graph.qq.com/oauth2.0/me?%s' % urllib.urlencode(params)

        response = urllib2.urlopen(url).read()
        v_str = str(response)[9:-3]  # 去掉callback的字符
        v_json = json.loads(v_str)

        openid = v_json['openid']
        self.openid = openid
        return openid

    def get_qq_info(self):
        """獲取QQ用戶的資料信息"""
        params = {'access_token': self.access_token,
                  'oauth_consumer_key': self.client_id,
                  'openid': self.openid}
        url = 'https://graph.qq.com/user/get_user_info?%s' % urllib.urlencode(params)

        response = urllib2.urlopen(url).read()
        return json.loads(response)

騰訊返回OpenID和QQ基本信息的內(nèi)容格式都不一樣计盒。

再回頭編輯views.py,添加回調(diào)地址的處理方法:

from django.shortcuts import render, HttpResponseRedirect, HttpResponse, reverse # reverse url逆向解析
from django.http import JsonResponse
from . import models
from .form import *
import json
import time
from django.conf import settings
from oauth_client import OAuthQQ

def qq_check(request):  # 第三方QQ登錄芽丹,回調(diào)函數(shù)
        """登錄之后北启,會(huì)跳轉(zhuǎn)到這里。需要判斷code和state"""
        request_code = request.GET.get('code')
        oauth_qq = OAuthQQ(settings.QQ_APP_ID, settings.QQ_KEY, settings.QQ_RECALL_URL)

        # 獲取access_token
        access_token = oauth_qq.get_access_token(request_code)
        time.sleep(0.05)  # 稍微休息一下拔第,避免發(fā)送urlopen的10060錯(cuò)誤
        open_id = oauth_qq.get_open_id()
        print open_id

        # 檢查open_id是否存在
        qq_open_id = models.OAuthQQ.objects.filter(qq_openid=str(open_id))
        print qq_open_id
        if qq_open_id:
            # 存在則獲取對(duì)應(yīng)的用戶咕村,并登錄
            user = qq_open_id[0].user.username
            print user
            request.session['username'] = user
            return HttpResponseRedirect('/web/')
        else:
            # 不存在,則跳轉(zhuǎn)到綁定用戶頁面
            infos = oauth_qq.get_qq_info()  # 獲取用戶信息
            url = '%s?open_id=%s&nickname=%s' % (reverse('bind_account'), open_id, infos['nickname'])
            return HttpResponseRedirect(url)

按照思路蚊俺,授權(quán)之后懈涛,調(diào)整到處理授權(quán)結(jié)果的頁面。獲取授權(quán)碼之后泳猬,用get_access_token方法得到access_token批钠。
再用access_token獲取OpenID宇植。坑出現(xiàn)了埋心,若不加time.sleep(0.05)休息一下的話指郁,會(huì)得到urlopen 10060錯(cuò)誤。
獲取到open_id之后拷呆,再判斷一下數(shù)據(jù)庫中是否存在闲坎。若存在,則已經(jīng)關(guān)聯(lián)對(duì)應(yīng)的用戶了茬斧,直接登錄該用戶腰懂。
若open_id不存在,則跳轉(zhuǎn)到綁定用戶的頁面项秉。該頁面需要知道open_id和QQ昵稱(為什么需要QQ昵稱绣溜,下一步會(huì)提到)。通過GET方式娄蔼,把這兩個(gè)參數(shù)寫在鏈接上即可傳遞過去怖喻。

本地調(diào)試,先本地打開授權(quán)頁面授權(quán)贷屎,得到一個(gè)回調(diào)地址罢防。回調(diào)地址上有授權(quán)碼唉侄,如下圖:

授權(quán)頁面
回調(diào)地址
QQ提醒

第5步咒吐、綁定用戶
上面提到若open_id在數(shù)據(jù)庫中不存在,則打開綁定用戶頁面属划。該頁面我設(shè)計(jì)成html表單恬叹,在templates下新建qq-bind-account.html文件。如下代碼:

{% extends 'base.html' %}

{% block title %}
    <title>QQ和賬戶綁定</title>
{% endblock %}

{% block head-js %}
{% endblock %}

{% block nav %}
{% endblock %}

{% block content %}
<form class="form-horizontal" enctype="multipart/form-data" action="" method="post">
    <div class="login">
        <h1><a href="{% url 'index' %}">Primumest</a></h1>
        <div class="login-bottom">
            <h2>HI同眯,![](/static/images/connect_qq.png){{ nickname }}绽昼!您已登錄。請(qǐng)綁定用戶须蜗,完成QQ登錄硅确。</h2>
            <div class="col-md-6">
                <div class="login-mail">
                    <input type="text" placeholder="請(qǐng)輸入你的賬戶名" name="username" required="">
                    <i class="fa fa-user"></i>
                </div>
                <div class="login-mail">
                    <input type="text" placeholder="請(qǐng)輸入你的昵稱" name="nickname" required="">
                    <i class="fa fa-users"></i>
                </div>
                <div class="login-mail">
                    <input type="password" placeholder="請(qǐng)輸入密碼" name="password" required="">
                    <i class="fa fa-lock"></i>
                </div>
                <div class="login-mail">
                    <input type="password" placeholder="請(qǐng)?jiān)俅屋斎朊艽a" name="password" required="">
                    <i class="fa fa-lock"></i>
                </div>
            </div>
            <div class="col-md-6 login-do">
                <label class="hvr-shutter-in-horizontal login-sub">
                    <input type="submit" value="確定">
                </label>
            </div>
            <div class="clearfix"></div>
        </div>
    </div>
</form>
    <!---->
    <div class="copy-right">
        <p>? 2017 JunXi. All Rights Reserved</p>
    </div>
{% endblock %}

接著,在views.py繼續(xù)編輯明肮,添加表單處理的對(duì)應(yīng)方法:

def bind_account(request):  # 綁定賬戶
    open_id = request.GET.get('open_id')
    nickname = request.GET.get('nickname')
    if request.method == 'POST' and request.POST:
        data = request.POST # 接收到前臺(tái)form表單傳過來的注冊(cè)賬戶信息
        user = models.UserProfile()
        username = data['username']
        password = data['password'].split(',')[0]
        user.username = username
        password = hash_sha256(password, username)
        user.password = password
        user.nickname = data['nickname']
        user.departments_id = 1
        user.save()
        oauthqq = models.OAuthQQ()
        oauthqq.qq_openid = open_id
        oauthqq.user_id = models.UserProfile.objects.get(username=username).id
        oauthqq.save()
        response = HttpResponseRedirect("/web/")
        request.session['username'] = username  # 設(shè)置session
        return response  # 返回首頁
    return render(request, 'qq-bind-account.html', locals())

訪問測(cè)試:
打開首頁


首頁

點(diǎn)擊QQ登錄


獲取授權(quán)頁面
綁定用戶界面

獲取授權(quán)并登錄


登錄成功了

寫完代碼之后菱农,本地測(cè)試可以通過。最后再部署到服務(wù)器并在QQ互聯(lián)提交審核柿估。一般審核要1~2天左右循未。若審核不通過,又不明白審核說明秫舌,就直接找客服問問的妖。

-----<我是分割線绣檬,下面是項(xiàng)目在pycharm中的展示>-----

項(xiàng)目展示1
項(xiàng)目展示2

-----<我是分割線,下面是urls.py嫂粟、view.py娇未、oauth_client.py完整的代碼>-----
urls.py

urlpatterns = [
    url(r'^oauth/qq/login', qq_login, name='qq_login'),
    url(r'^oauth/qq/check', qq_check, name='qq_check'),
    url(r'^oauth/bind/account', bind_account, name='bind_account'),
]

views.py

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
__author__ = 'junxi'

from django.shortcuts import render, HttpResponseRedirect, HttpResponse, reverse # reverse url逆向解析
from django.http import JsonResponse
from . import models
from .form import *
from script.salt_api import salt
from script.web_ssh import webssh
from django.contrib.auth.hashers import make_password, check_password
# from django.forms.models import model_to_dict
from django.core import serializers
import datetime
import json
import hashlib
import re
import time
import os
from django.conf import settings
from oauth_client import OAuthQQ


def hash_sha256(password, username):  # sha256加密
    sha256 = hashlib.sha256()
    sha256.update((password + username).encode('utf-8'))
    sha256_password = sha256.hexdigest()
    return sha256_password


def qq_login(request):  # 第三方QQ登錄
    oauth_qq = OAuthQQ(settings.QQ_APP_ID, settings.QQ_KEY, settings.QQ_RECALL_URL)

    # 獲取 得到Authorization Code的地址
    url = oauth_qq.get_auth_url()
    # 重定向到授權(quán)頁面
    return HttpResponseRedirect(url)


def qq_check(request):  # 第三方QQ登錄,回調(diào)函數(shù)
        """登錄之后赋元,會(huì)跳轉(zhuǎn)到這里忘蟹。需要判斷code和state"""
        request_code = request.GET.get('code')
        oauth_qq = OAuthQQ(settings.QQ_APP_ID, settings.QQ_KEY, settings.QQ_RECALL_URL)

        # 獲取access_token
        access_token = oauth_qq.get_access_token(request_code)
        time.sleep(0.05)  # 稍微休息一下飒房,避免發(fā)送urlopen的10060錯(cuò)誤
        open_id = oauth_qq.get_open_id()
        print open_id

        # 檢查open_id是否存在
        qq_open_id = models.OAuthQQ.objects.filter(qq_openid=str(open_id))
        print qq_open_id
        if qq_open_id:
            # 存在則獲取對(duì)應(yīng)的用戶搁凸,并登錄
            user = qq_open_id[0].user.username
            print user
            request.session['username'] = user
            return HttpResponseRedirect('/web/')
        else:
            # 不存在,則跳轉(zhuǎn)到綁定用戶頁面
            infos = oauth_qq.get_qq_info()  # 獲取用戶信息
            url = '%s?open_id=%s&nickname=%s' % (reverse('bind_account'), open_id, infos['nickname'])
            return HttpResponseRedirect(url)


def bind_account(request):  # 綁定賬戶
    open_id = request.GET.get('open_id')
    nickname = request.GET.get('nickname')
    if request.method == 'POST' and request.POST:
        data = request.POST # 接收到前臺(tái)form表單傳過來的注冊(cè)賬戶信息
        user = models.UserProfile()
        username = data['username']
        password = data['password'].split(',')[0]
        user.username = username
        password = hash_sha256(password, username)
        user.password = password
        user.nickname = data['nickname']
        user.departments_id = 1
        user.save()
        oauthqq = models.OAuthQQ()
        oauthqq.qq_openid = open_id
        oauthqq.user_id = models.UserProfile.objects.get(username=username).id
        oauthqq.save()
        response = HttpResponseRedirect("/web/")
        request.session['username'] = username  # 設(shè)置session
        return response  # 返回首頁
    return render(request, 'qq-bind-account.html', locals())

oauth_client.py

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
__author__ = 'junxi'

import json
import urllib, urllib2, urlparse


class OAuthQQ:
    def __init__(self, client_id, client_key, redirect_uri):
        self.client_id = client_id
        self.client_key = client_key
        self.redirect_uri = redirect_uri

    def get_auth_url(self):
        """獲取授權(quán)頁面的網(wǎng)址"""
        params = {'client_id': self.client_id,
                  'response_type': 'code',
                  'redirect_uri': self.redirect_uri,
                  'scope': 'get_user_info',
                  'state': 1}
        url = 'https://graph.qq.com/oauth2.0/authorize?%s' % urllib.urlencode(params)
        return url

    def get_access_token(self, code):
        """根據(jù)code獲取access_token"""
        params = {'grant_type': 'authorization_code',
                  'client_id': self.client_id,
                  'client_secret': self.client_key,
                  'code': code,
                  'redirect_uri': self.redirect_uri}    # 回調(diào)地址
        url = 'https://graph.qq.com/oauth2.0/token?%s' % urllib.urlencode(params)

        # 訪問該網(wǎng)址狠毯,獲取access_token
        response = urllib2.urlopen(url).read()
        result = urlparse.parse_qs(response, True)

        access_token = str(result['access_token'][0])
        self.access_token = access_token
        return access_token

    def get_open_id(self):
        """獲取QQ的OpenID"""
        params = {'access_token': self.access_token}
        url = 'https://graph.qq.com/oauth2.0/me?%s' % urllib.urlencode(params)

        response = urllib2.urlopen(url).read()
        v_str = str(response)[9:-3]  # 去掉callback的字符
        v_json = json.loads(v_str)

        openid = v_json['openid']
        self.openid = openid
        return openid

    def get_qq_info(self):
        """獲取QQ用戶的資料信息"""
        params = {'access_token': self.access_token,
                  'oauth_consumer_key': self.client_id,
                  'openid': self.openid}
        url = 'https://graph.qq.com/user/get_user_info?%s' % urllib.urlencode(params)

        response = urllib2.urlopen(url).read()
        return json.loads(response)

<br />
參考文章
护糖。。嚼松。嫡良。。献酗。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末寝受,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子罕偎,更是在濱河造成了極大的恐慌很澄,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件颜及,死亡現(xiàn)場(chǎng)離奇詭異甩苛,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)俏站,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門讯蒲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人肄扎,你說我怎么就攤上這事墨林。” “怎么了犯祠?”我有些...
    開封第一講書人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵旭等,是天一觀的道長。 經(jīng)常有香客問我雷则,道長辆雾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任月劈,我火速辦了婚禮度迂,結(jié)果婚禮上藤乙,老公的妹妹穿的比我還像新娘。我一直安慰自己惭墓,他們只是感情好坛梁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著腊凶,像睡著了一般划咐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上钧萍,一...
    開封第一講書人閱讀 51,365評(píng)論 1 302
  • 那天褐缠,我揣著相機(jī)與錄音,去河邊找鬼风瘦。 笑死队魏,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的万搔。 我是一名探鬼主播胡桨,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼瞬雹!你這毒婦竟也來了昧谊?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤酗捌,失蹤者是張志新(化名)和其女友劉穎呢诬,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體意敛,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡馅巷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了草姻。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钓猬。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖撩独,靈堂內(nèi)的尸體忽然破棺而出敞曹,到底是詐尸還是另有隱情,我是刑警寧澤综膀,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布澳迫,位于F島的核電站,受9級(jí)特大地震影響剧劝,放射性物質(zhì)發(fā)生泄漏橄登。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拢锹。 院中可真熱鬧谣妻,春花似錦、人聲如沸卒稳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽充坑。三九已至减江,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間捻爷,已是汗流浹背辈灼。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留役衡,地道東北人茵休。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓薪棒,卻偏偏與公主長得像手蝎,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子俐芯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容