鑒權(quán)

常見的鑒權(quán)方式:Session/Cookie、Token(JWT)汰规、OAuth蜜唾、SSO

Session/Cookie

Session基于CookieSession存在服務(wù)端找田,Cookie存在客戶端。

// 服務(wù)端 - Node
const http = require('http');
http.createServer((req, res) => {
    req.headers.cookie  // 獲取客戶端攜帶的Cookie
    res.setHeader('Set-Cookie', 'cookie1=abc;')  // 讓客戶端設(shè)置Cookie
    res.end()
}).listen(3000)

客戶端收到的Response Headers:

   Set-Cookie: cookie1=abc;

客戶端再次請求時着憨,會在 Request Headers 中攜帶 Cookie

   Cookie: cookie1=abc

Cookie的容量有限,且容易被篡改务嫡,不安全甲抖,所以出現(xiàn)了Session
在客戶端的Cookie中,存儲一個隨機(jī)的Session Id心铃,Session信息存儲在服務(wù)端

// 模擬實現(xiàn)Cookie-Session模式
let session = {}, sessionKey = 'sid'
http.createServer((req, res) => {
    const cookie req.headers.cookie
    if(cookie && cookie.indexOf(sessionKey) !== -1) {
        res.end('Come Back!')
        // 存在准谚,取出Session
        const pattern = new RegExp(`${sessionKey}=(^;]+);?\s*`)
        const sid = pattern.exec(cookie)[1]
        session[sid]  // Session
    } else {
        // 不存在Cookie-Session
        const sid = (Math.random() * 999999).toFixed()
        // 設(shè)置Cookie
        res.setHeader('Set-Cookie', `${sessionKey}=${sid}`)
        session[sid] = { name: 'Jack' }
        res.end('Hi, Jack')
    }
}).listen(3000)

Session會話機(jī)制是一種服務(wù)端機(jī)制,它使用類似哈希表的結(jié)果來保存信息去扣。

在客戶端首次訪問服務(wù)器時創(chuàng)建Session柱衔,并為這個Session生成一個唯一的表示字符串sid,作為鍵愉棱。如果需要唆铐,還會通過密匙對 sid 進(jìn)行簽名處理,避免客戶端篡改奔滑。把 sid 作為 Cookie 返回給客戶端艾岂。客戶端在隨后的HTTP請求中會攜帶這個sid朋其,服務(wù)端通過這個sid查詢客戶端的Session信息王浴。

哈希 Hash

  1. 哈希 Hash 的特點
    • 把一個不定長摘要定長結(jié)果
    • 摘要 xialaoshi -> x4sdfdsafsdafl3s3 -- 按照某種規(guī)則進(jìn)行摘要脆炎,防篡改
    • 雪崩效應(yīng):牽一發(fā)動全身,如 xialaoshizialaoshi 雖然只有一個字母不同氓辣,但摘要的結(jié)果完全不同秒裕,讓人完全找不到規(guī)律。
  2. 常見哈希算法:MD5钞啸、SHA1几蜻、hmac
  3. 摘要(加密算法)
    • 對稱DES
    • 非對稱RSA
  4. koa-session 中啟用簽名
const Koa = require('koa'), session = require('koa-session')
const app = new Koa()
app.keys = ['some secret']  //用于對cookie簽名的key
const SESS_CONFIG = {
    key: 'ply:sess',  // cookie的鍵名
    maxAge: 86400000,
    httpOnly: true,  // 僅允許服務(wù)器修改
    signed: true  // 啟用簽名
}
app.use(session(SESS_CONFIG, app))

Session通常存在于內(nèi)存、Redis等介質(zhì)中爽撒,但分布式部署無法共享內(nèi)存入蛆,所以大多數(shù)情況下存儲于Redis中。

Token 令牌

Token是一個獨立的概念硕勿,是通過認(rèn)證后發(fā)放的某個 憑證哨毁,這個憑證可以通過Cookie、自定義http請求頭(如X-Token)源武,URLquery進(jìn)行傳遞扼褪。所以Token不存在跨域、跨平臺的問題粱栖。

  • 常見加密形式(攜帶信息):用戶Id + 過期時間 + 簽名
  • Token需要服務(wù)端查庫驗證是否有效话浇,通常存儲于Redis中。

JWT - 服務(wù)端無狀態(tài)化

JWT Json Web Token闹究,是Token的子集幔崖,是一種規(guī)則,采用Json格式以及附帶一些規(guī)范約束渣淤,將用戶信息加密到 Token 中赏寇。服務(wù)器不保存任何用戶狀態(tài)信息(無需查庫),而是通過保存的密匙校驗 Token价认,也就是說 服務(wù)端是無狀態(tài)的嗅定,即使服務(wù)重啟也不會有影響。

JWT的加密過程(原理) 包括三部分:頭部header用踩,載荷payload渠退,簽名signature,用 . 分隔脐彩。

  • Header 用于描述元信息碎乃,通常包括Token類型和Signature的加密算法
    {
       "alg": "HS256",  // 默認(rèn)的哈希(加密)算法
       "typ": "JWT"     // Token類型
    }
    
    經(jīng)過 base64 編碼,得到第一部分
  • Payload 載荷信息惠奸,包含一些聲明Claim(實體描述荠锭,通常是一個用戶信息,還有一些其他的元數(shù)據(jù))晨川,即攜帶希望向服務(wù)器發(fā)送的信息证九。
    這些信息可以是官方字段如iss(Issuer)删豺、sub(Subject)、exp(Expiration time)愧怜,也可以是自定義字段如userId呀页,data
    {
       "iss": "JWT Builder",  // 該JWT的簽發(fā)者
       "sub": "aaa@example.com",     // 該JWT所面向的用戶
       "exp": 1448333419,     // 過期時間
       "userId": "b08f86af-35da-48f2-8fab-cef3904660bd"  // 用戶Id
    }
    
    經(jīng)過base64編碼,得到第二部分
  • Signature
    第一部分 + "." + 第二個部分 拼接成字符串拥坛,通過 Header 中聲明的加密方式進(jìn)行加鹽secret組合加密蓬蝶,得到第三部分。
    加鹽secret 也就是服務(wù)端提供的私鑰猜惋,防篡改丸氛。解密Token時僅僅使用設(shè)定的 secret,無需查詢數(shù)據(jù)庫著摔,所以secret一定不能泄露;捍堋!谍咆!
    一旦客戶端得到這個secret禾锤,那就意味著客戶端可以自我簽發(fā)JWT了!

第一部分 + "." + 第二個部分 + "." + 第三個部分 = JWT

由此可知摹察,JWT(Token) 并不是為了隱藏或保密數(shù)據(jù)恩掷,而是為了確保它是被授權(quán)的,所以其中不能放諸如用戶密碼等 敏感信息供嚎。

// 前端
axios.interceptors.request.use(config => {
    const token = window.localStorage.getItem('token')
    if(token) {
        // 通常約定 Bearer 是 JWT 的認(rèn)證頭部
        config.headers.common['Authorization'] = 'Bearer ' + token
    }
    return config
}, err => Promise.reject(err))

Node Koa 后端:

  • koa黄娘、koa-router、koa-bodyparser克滴、koa-static
  • jsonwebtoken寸宏、koa-jwt、koa2-cors(跨域)

對比

  • Cookie-Session 模式會受跨域偿曙、分布式部署、服務(wù)重啟的影響羔巢;
  • Token + Redis 模式需要每次都查詢數(shù)據(jù)庫望忆,驗證Token是否有效;
  • JWT 是一種認(rèn)證授權(quán)機(jī)制竿秆,服務(wù)端無狀態(tài)(無需存儲)启摄,也就不能主動清除,不能踢離線幽钢。

OAuth

隨著大量開放平臺的出現(xiàn)歉备,建立在開放平臺之上的各種第三方應(yīng)用也在大量冒出。出于對安全性和統(tǒng)一標(biāo)準(zhǔn)的要求匪燕,就有了OAuth協(xié)議蕾羊。

簡單來說喧笔,OAuth是一種開放的協(xié)議,一種授權(quán)機(jī)制龟再,它能為第三方應(yīng)用提供一種簡單的標(biāo)準(zhǔn)方式去訪問需要用戶授權(quán)的API服務(wù)书闸。而且在為第三方提供服務(wù)的過程中,能夠保護(hù)用戶賬號的安全利凑。

2007年OAuth1.0浆劲,存在嚴(yán)重漏洞。2009年6月OAuth1.0 Revision A哀澈,修復(fù)了前一版本的安全漏洞牌借。
2010年4月OAuth2.0,與1.0互不兼容割按。OAuth 2.0也是目前最流行的授權(quán)機(jī)制膨报,授權(quán)第三方應(yīng)用,獲取用戶數(shù)據(jù)哲虾。

舉個栗子:
我們想做一個關(guān)于新浪微博的第三方應(yīng)用丙躏,那么就需要新浪微博提供一系列API,但前提是要去授權(quán)驗證束凑,這就用到OAuth了晒旅。作為第三方開發(fā)者,我們并沒有得到用戶實質(zhì)性的私密信息汪诉,只是獲取了一個短期的進(jìn)入令牌(必須保密废恋,不能泄露),確保了用戶賬號的安全扒寄。

在應(yīng)用OAuth時鱼鼓,常常與OpenID作比較:
OAuth的關(guān)注點在于授權(quán),OpenID的側(cè)重于證明鑒定该编。簡單來說迄本,OAuth解決用戶能(想)做什么,是 WHAT 的問題课竣;OpenID則為我們驗證用戶是誰嘉赎,解決WHO的問題

1.0 與 2.0 的授權(quán)方式不同
瀏覽器、目標(biāo)服務(wù)器于樟、第三方認(rèn)證服務(wù)器

  • 2.0授權(quán)過程分3步:
    獲取授權(quán)碼Authorization Code --> 換取訪問令牌access_token --> 訪問授權(quán)資源
    具體過程:瀏覽器向目標(biāo)服務(wù)器發(fā)起認(rèn)證請求 --> 目標(biāo)服務(wù)器通知瀏覽器重定向到第三方認(rèn)證服務(wù)器 --> 瀏覽器輸入第三方認(rèn)證的用戶名和密碼并發(fā)送 --> 認(rèn)證成功后回調(diào)給目的服務(wù)器授權(quán)碼--> 目的服務(wù)器使用授權(quán)碼向第三方認(rèn)證服務(wù)器換取訪問令牌 --> 第三方認(rèn)證服務(wù)器返回令牌給目的服務(wù)器 --> 目的服務(wù)器通知瀏覽器刷新頁面公条,登錄授權(quán)成功,使用令牌訪問得到授權(quán)的資源
OAuth2x之授權(quán)碼
  • 1.0授權(quán)過程分4步
    1. 請求未授權(quán)的Request Token (比如顯示新浪微博的授權(quán)登錄界面)
    2. 請求授權(quán)的Request Token迂曲,用戶確認(rèn)授權(quán)靶橱,認(rèn)證服務(wù)器返回授權(quán)的OAuth Token
    3. OAuth Token換取Access Token,獲得訪問令牌oauth_tokenoauth_token_secret
    4. 用訪問令牌訪問得到授權(quán)的資源
OAuth1x

雖然1.0協(xié)議每個Token都有加密,2.0則不需要关霸,但2.0要求使用 https 協(xié)議传黄,安全性高于1.0;而且2.0充分考慮了客戶端的各種姿態(tài)谒拴,提供了多種途徑獲取訪問令牌尝江,包括授權(quán)碼,客戶端私有整數(shù)英上,資源擁有者密碼證書炭序,刷新令牌等等,且驗證過程更加簡潔苍日。相比之下惭聂,1.0只有一個用戶授權(quán)流程。

Github認(rèn)證為例
需要先開通Github賬號相恃,主頁頭像 --> Settings --> Developer settings --> OAuth Apps --> New OAuth App 注冊一個第三方OAuth認(rèn)證的應(yīng)用(應(yīng)用名稱辜纲、應(yīng)用的主頁URL、認(rèn)證回調(diào)的URL)拦耐,得到 Client ID耕腾,Client Secret

  • 前端頁面提供第三方Github登錄的入口:
<a href="/github/login">login with github</a>
  • 后端處理第三方認(rèn)證:
const Koa = require('koa'),
    Router = require('@koa/router'),
    static = require('koa-static'),
    querystring = require('querystring'),
    axios = require('axios');
const config = {
    client_id: '76a2dacb24ead9fc4596',
    client_secret: '657124b0a8073d5538d12ad68f6d56114761283c'
}
// github 的認(rèn)證接口
const OAuthURL = 'https://github.com/login/oauth/authorize';
// github 的Token接口
const TokenURL = 'https://github.com/login/oauth/access_token'
let thirdUser;  // 保存第三方認(rèn)證用戶的數(shù)據(jù)
const app = new Koa();
const router = new Router();
app.use(static(__dirname + '/'));

router.get('/github/login', async ctx => {
    // 重定向到Github認(rèn)證接口
    const url = OAuthURL + '?client_id=' + config.client_id;
    ctx.redirect(url)
});

/**
Github上配置的認(rèn)證回調(diào)接口:
    http://localhost:7000/auth/github/callback
*/ 
router.get('/auth/github/callback', async ctx => {
    // 獲取到授權(quán)碼Code
    const code = ctx.query.code;
    const params = Object.assign({ code }, config)
    // 根據(jù)授權(quán)碼 換取令牌Token
    let resp = await axios.post(TokenURL, params)
    const access_token = querystring.parse(resp.data).access_token
    // 已經(jīng)獲取了Token,可以請求Github的接口了:獲取用戶數(shù)據(jù)
    thirdUser = await axios.get('https://api.github.com/user?access_token='+access_token)
    // 重定向到主頁
    ctx.redirect('/home')
});
router.get('/home', async ctx => {
    const { login, avatar_url } = thirdUser.data
    ctx.body = `
        <h1>Hello ${login}</h1>
        <img src="${avatar_url}" />
    `
})

app.use(router.routes()).use(router.allowedMethods()).listen(7000);

SSO

單點登錄:Single Sign On - SSO 是一個在多系統(tǒng)共存的環(huán)境下杀糯,用戶登錄其中一個系統(tǒng)扫俺,便可在其他所有系統(tǒng)中得到授權(quán) 而無需再次登錄。包括 單點登錄單點注銷 兩部分固翰。

Web系統(tǒng)由單系統(tǒng)發(fā)展成多個系統(tǒng)組成的應(yīng)用群狼纬,復(fù)雜性應(yīng)該由系統(tǒng)內(nèi)部承擔(dān),而不是用戶骂际。無論web系統(tǒng)內(nèi)部多么復(fù)雜疗琉,對用戶而言,都是一個統(tǒng)一的整體歉铝;也就是說盈简,用戶訪問Web系統(tǒng)的整個應(yīng)用群與訪問單個系統(tǒng)一樣,登錄/注銷只要一次就夠了太示。

單點登錄

單點登錄可分為同域和跨域兩種場景

同域

同域單點登錄的核心就是共享Cookie柠贤,所有子系統(tǒng)都使用同一個一級域名,通過不同的二級域名來區(qū)分先匪。
舉個栗子:公司有一個一級域名 zlt.com,三個子系統(tǒng):門戶系統(tǒng)sso.zlt.com弃衍,應(yīng)用1app1.zlt.com呀非,應(yīng)用2app2.zlt.com

  1. 設(shè)置它們的Cookie域為一級域名(domain=zlt.com),這樣就可以共享門戶系統(tǒng)的Cookie給所有使用 *.zlt.com 作為域名的系統(tǒng)。
  2. 使用 Spring Session 等技術(shù)讓所有系統(tǒng)共享Session岸裙。這樣只要門戶系統(tǒng)登錄之后猖败,無論跳轉(zhuǎn) 應(yīng)用1 還是應(yīng)用2,都能通過門戶系統(tǒng)Cookie中的sessionId讀取到Session中的登錄信息降允,實現(xiàn)單點登錄恩闻。

然而,共享Cookie的方式存在眾多局限剧董。首先幢尚,應(yīng)用群域名必須統(tǒng)一;其次翅楼,應(yīng)用群各系統(tǒng)使用的技術(shù)(至少是Web服務(wù)器)要相同尉剩,否則Cookiekey值(TomcatJSESSIONID)不同,無法維持會話毅臊,即共享Cookie的方式是無法實現(xiàn)跨語言技術(shù)平臺登錄的理茎,比如java、php管嬉、.net系統(tǒng)之間皂林;第三,Cookie本身不安全蚯撩。

跨域

單點登錄之間的系統(tǒng)域名不同础倍,無法共享Cookie,需要一個獨立的 授權(quán)系統(tǒng)/認(rèn)證中心求厕。子系統(tǒng)本身不參與登錄著隆,而是通過認(rèn)證中心驗證身份,完成間接授權(quán)呀癣。當(dāng)一個系統(tǒng)登錄成功后寇甸,認(rèn)證中心會頒發(fā)一個令牌給子系統(tǒng),子系統(tǒng)拿著令牌去獲取受保護(hù)的資源味赃。為了減少頻繁認(rèn)證嫂用,各個子系統(tǒng)在被認(rèn)證中心授權(quán)以后,會建立一個局部會話沼沈,在一定時間內(nèi)無需再次向認(rèn)證中心發(fā)起認(rèn)證流酬。

單點登錄
  • 用戶訪問系統(tǒng)1的受保護(hù)資源,系統(tǒng)1發(fā)現(xiàn)用戶未登錄列另,跳轉(zhuǎn)至SSO認(rèn)證中心芽腾,并將自己的地址作為參數(shù)
  • SSO認(rèn)證中心發(fā)現(xiàn)用戶未登錄,將用戶引導(dǎo)至登錄頁面
  • 用戶輸入用戶名密碼提交登錄申請
  • SSO認(rèn)證中心校驗用戶信息页衙,創(chuàng)建用戶與SSO認(rèn)證中心之間的會話摊滔,稱為全局會話阴绢,同時創(chuàng)建授權(quán)令牌
  • SSO認(rèn)證中心帶著令牌跳轉(zhuǎn)回最初的請求地址(系統(tǒng)1)
  • 系統(tǒng)1拿到令牌,去SSO認(rèn)證中心校驗令牌是否有效(安全性艰躺,必須校驗)
  • SSO認(rèn)證中心校驗令牌呻袭,返回有效,注冊系統(tǒng)1
  • 系統(tǒng)1使用該令牌創(chuàng)建與用戶的會話腺兴,稱為局部會話左电,返回受保護(hù)資源
  • 用戶訪問系統(tǒng)2的受保護(hù)資源,系統(tǒng)2發(fā)現(xiàn)用戶未登錄页响,跳轉(zhuǎn)至SSO認(rèn)證中心篓足,并將自己的地址作為參數(shù)
  • SSO認(rèn)證中心發(fā)現(xiàn)用戶已登錄,跳轉(zhuǎn)回系統(tǒng)2的地址拘泞,并附上令牌
  • 系統(tǒng)2拿到令牌纷纫,去SSO認(rèn)證中心校驗令牌是否有效,SSO認(rèn)證中心返回有效陪腌,注冊系統(tǒng)2
  • 系統(tǒng)2使用該令牌創(chuàng)建與用戶的局部會話辱魁,返回受保護(hù)資源

用戶登錄成功之后,會與SSO認(rèn)證中心及各個子系統(tǒng)建立會話诗鸭,用戶與SSO認(rèn)證中心建立的會話稱為全局會話染簇,與各個子系統(tǒng)建立的會話稱為局部會話。局部會話建立之后强岸,用戶訪問子系統(tǒng)受保護(hù)資源將不再通過SSO認(rèn)證中心锻弓。

全局會話局部會話的約束關(guān)系:

  • 局部會話存在,全局會話一定存在
  • 全局會話存在蝌箍,局部會話不一定存在
  • 全局會話銷毀青灼,局部會話必須銷毀

SSO系統(tǒng)登錄后,帶著令牌跳回原業(yè)務(wù)系統(tǒng)時妓盲,業(yè)務(wù)系統(tǒng)還要拿令牌再次訪問SSO進(jìn)行驗證杂拨,這個步驟看似有點多余。如果SSO登錄認(rèn)證通過后悯衬,通過回調(diào)地址將用戶信息返回給原業(yè)務(wù)系統(tǒng)弹沽,原業(yè)務(wù)系統(tǒng)直接設(shè)置登錄狀態(tài),這樣流程簡單筋粗,也完成了登錄娜亿,不是很好嗎辰斋?!
其實問題是很嚴(yán)重的旁仿,如果在SSO沒有登錄办悟,而是直接在瀏覽器中敲入回調(diào)的地址炫加,并帶上偽造的用戶信息魄健,是不是業(yè)務(wù)系統(tǒng)也認(rèn)為登錄了呢?這是很可怕的绿满!

單點注銷

單點登錄自然也要單點注銷,在一個子系統(tǒng)中注銷姐叁,所有子系統(tǒng)的會話都將被銷毀挠唆;

單點注銷

SSO認(rèn)證中心一直監(jiān)聽全局會話的狀態(tài),一旦全局會話銷毀嘱吗,監(jiān)聽器將通知所有注冊系統(tǒng)執(zhí)行注銷操作

  • 用戶向 系統(tǒng)1 發(fā)起注銷請求玄组;
  • 系統(tǒng)1 根據(jù)與用戶建立的會話id拿到令牌,向SSO認(rèn)證中心發(fā)起注銷請求谒麦;
  • SSO認(rèn)證中心校驗令牌有效俄讹,銷毀全局會話,同時取出所有用此令牌注冊的系統(tǒng)地址绕德,向所有注冊系統(tǒng)發(fā)起注銷請求患膛;
  • 各注冊系統(tǒng)接收SSO認(rèn)證中心的注銷請求,銷毀局部會話耻蛇;
  • SSO認(rèn)證中心引導(dǎo)用戶至登錄頁面踪蹬。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市臣咖,隨后出現(xiàn)的幾起案子延曙,更是在濱河造成了極大的恐慌,老刑警劉巖亡哄,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件枝缔,死亡現(xiàn)場離奇詭異,居然都是意外死亡蚊惯,警方通過查閱死者的電腦和手機(jī)愿卸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來截型,“玉大人趴荸,你說我怎么就攤上這事』陆梗” “怎么了发钝?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長波闹。 經(jīng)常有香客問我酝豪,道長,這世上最難降的妖魔是什么精堕? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任孵淘,我火速辦了婚禮,結(jié)果婚禮上歹篓,老公的妹妹穿的比我還像新娘瘫证。我一直安慰自己揉阎,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布背捌。 她就那樣靜靜地躺著毙籽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪毡庆。 梳的紋絲不亂的頭發(fā)上惧财,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機(jī)與錄音扭仁,去河邊找鬼。 笑死厅翔,一個胖子當(dāng)著我的面吹牛乖坠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播刀闷,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼熊泵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了甸昏?” 一聲冷哼從身側(cè)響起顽分,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎施蜜,沒想到半個月后卒蘸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡翻默,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年缸沃,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片修械。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡趾牧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出肯污,到底是詐尸還是另有隱情翘单,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布蹦渣,位于F島的核電站哄芜,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏柬唯。R本人自食惡果不足惜忠烛,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望权逗。 院中可真熱鬧美尸,春花似錦冤议、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至胯陋,卻和暖如春蕊温,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背遏乔。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工义矛, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人盟萨。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓凉翻,卻偏偏與公主長得像,于是被迫代替她去往敵國和親捻激。 傳聞我的和親對象是個殘疾皇子制轰,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354