GithubHelp home page GithubHelp logo

charleslo1 / weapp-cookie Goto Github PK

View Code? Open in Web Editor NEW
823.0 12.0 102.0 999 KB

一行代码让微信、头条、百度、支付宝小程序支持 cookie,兼容 uni-app 🍪🚀 One line of code allows weapp to support cookie(wx weixin wxapp cookie)

License: MIT License

JavaScript 100.00%

weapp-cookie's Introduction

weapp-cookie

一行代码让微信、头条、百度、支付宝小程序支持 cookie,兼容 uni-app

weapp-cookie

Intro

小程序原生的 request 网络请求接口并不支持传统的 Cookie,但有时候我们现有的后端接口确于依赖 Cookie(比如服务器用户登录态),这个库可用一行代码为你的小程序实现 Cookie 机制,以保证基于 cookie 的服务会话不会失效,与 web 端共用会话机制

Featrues

  • 一行代码让小程序支持 cookie
  • 可使用 api 获取、设置 cookie
  • 支持 domain/path 作用域

Install

npm install weapp-cookie --save

# 将 npm 包复制到 vendor 文件夹,避免小程序可能不能找到文件(Tips:支持npm包的开发环境无需此步)
cp -rf ./node_modules/ ./vendor/

Usage

以微信小程序为例,在小程序根目录的 app.js 一行代码引入即可

// app.js
import './vendor/weapp-cookie/dist/weapp-cookie'

// tips: 使用 uni-app/wepy/mpvue 等支持npm包的环境可以直接在入口 js 引入 weapp-cookie 模块
// import 'weapp-cookie'

App({
    onLaunch: function () { }
    // ...
})

原来的 wx.request 调用方式保持不变,引入后 weapp-cookie 会在底层自动代理 wx.request 的接口访问,以支持 cookie 存储和发送

// pages/home/index.js

Page({
    onLoad: function () {
        wx.request({
            url: 'https://example.com/login',
            data: {
                username: 'admin',
                password: '123456'
            },
            success: function (res) {
                /*
                 * 接口调用成功后 weapp-cookie 会自动保存后端发送的所有Cookie(比如:SessionID)
                 * 并在后续的所有请求中带上,以保证基于 cookie 的服务器会话机制不会失效,
                 * 实现与 web 端共用会话机制(无需再手动维护 3rd_session_key) 
                 */
            }
        })
    }
})

cookie 操作可通过 api 调用

import cookies from 'weapp-cookie'

// 获取 cookie
let token = cookies.get('csrf_token', 'example.com')

// 设置 cookie
let cookie = cookies.set('uid', 100, { domain: 'example.com' })

// 删除 cookie
let isRemoved = cookies.remove('uid', 'example.com')

// 判断是否存在 cookie
let hasToken = cookies.has('uid', 'example.com')

// ... 详情请参考 Api

使用和配置别名:由于微信小程序的安全机制,在小程序插件环境下 wx.request 不允许被重写,所以需使用内置别名或自定义别名来支持 cookie 请求

import cookies from 'weapp-cookie'

// 使用内置别名
wx.requestWithCookie({
    url: 'https://example.com/user/current',
    success: function (res) {
        console.log(res)
    }
})

// 配置自定义别名
cookies.config({ requestAlias: 'requestx' })

// 使用自定义别名
wx.requestx({
    url: 'https://example.com/user/current',
    success: function (res) {
        console.log(res)
    }
})

Api

CookieStore

import cookies from 'weapp-cookie'

/**
* 获取 cookie 值
* @param {String} name       cookie 名称
* @param {String} [domain]   指定域名(可选)
* @return {String}           cookie 值
*/
cookies.get(String name, String domain)

/**
* 设置 cookie
* @param {String}  name              cookie 名称
* @param {String}  value             cookie 值
* @param {Object}  options           cookie 选项
* @param {String}  options.domain    设置域名
* @param {String}  [options.path]      
* @param {Date}    [options.expires]
* @param {Number}  [options.maxAge]
* @param {Boolean} [options.httpOnly]
* @return {Cookie}           cookie 对象
*/
cookies.set(String name, String value, Object options)

/**
* 是否存在某个 cookie
* @param  {String}  name       cookie 名称
* @param  {String}  [domain]   指定域名(可选,不指定则任意域名包含名称为 name 的 cokkie 即为存在)
* @return {Boolean}            是否存在
*/
cookies.has(String name, String domain)

/**
* 删除 cookie
* @param  {Array}  name      cookie 键
* @param  {String} [domain]  指定域名(可选,不指定则删除所有域名中名称为 name 的 cookie)
* @return {Boolean}          是否删除成功
*/
cookies.remove(String name, String domain)

/**
* 获取 cookie 对象
* @param {String} name       cookie 名称
* @param {String} [domain]   指定域名(可选)
* @return {Cookie}           cookie 对象
*/
cookies.getCookie(String name, String domain)

/**
* 获取 cookies JSON对象
* @param  {String} [domain]  指定域名(可选,不指定则获取包含所有域名的 cookie 值对象)
* @return {Object}           cookie JSON对象
*/
cookies.getCookies(String domain)

/**
* 清除 cookie
* @param  {String} [domain]  指定域名(可选,不指定则清除所有域名 cookie)
* @return {Boolean}          是否清除成功
*/
cookies.clearCookies (domain)

/**
* 获取所有存储的域名和 cookies 结构
* @return {Object}   obj   结构JSON对象
*/
cookies.dir(domain)

Cookie

import cookies from 'weapp-cookie'

// 获取 cookie 对象
let cookie = cookies.getCookie('uuid', 'example.com')

// ===== cookie 属性 =====
cookie.name:        String
cookie.value:       String
cookie.domain:      String
cookie.path:        String
cookie.expires:     Date
cookie.maxAge:      Number
cookie.httpOnly:    Boolean

// ===== cookie 方法 =====

/**
 * 验证 cookie 是否过期
 * @return {Boolean} 是否过期
 */
cookie.isExpired()

/**
 * 验证 cookie 是否可持久化
 * @return {Boolean} 是否可持久化
 */
cookie.isPersistence()

star

如果对你有用,欢迎 star ^_^

weapp-cookie's People

Contributors

charleslo1 avatar dependabot[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

weapp-cookie's Issues

iOS设备上传之后,cookie设置无效

场景:使用MacOS系统开发,在模拟器、真机调试上测试通过,上传体验版之后安卓设备测试通过,iOS设备测试发现问题,并没有设置到cookie。

web cookie?

项目的cookie是指wx.request的么,不是内嵌webView的cookie吧

uni-app中无法重写和新增uni对象的属性

解决方案:
src/cookieShim.js文件中

Object.defineProperties(api, {
  // request
  requestWithCookie: {
	  value: requestProxy,
  },
  // uploadFile
  uploadFileWithCookie: {
	  value: uploadFileProxy,
  },
  // downloadFile
  downloadFileWithCookie: {
	  value: downloadFileProxy,
  }
})

这里Object.defineProperties(api 中的api改成uni即可。
搞不懂为什么不能用返回过来的uni对象,必须用字面量。
换成eval('uni')也不可以.
暂且这么用一下吧

泛域名的cookie 查询失败

a.xxx.com把cookie 种在了 domain:xxx.com, 接下来请求b.xxx.com 的时候不会带上cookie, requestProxy 中对domain的处理兼容性不好

用户本地时间修改后,导致cookies 是否失效判断出错

例如当前实际时间是 2023-05-05 10:00:00
服务器返回的cookie 失效时间5天有效,为2023-05-10 10:00:00

当用户调整他手机的本地时间为 2023-05-30 10:00:00 时,服务器返回的 cookie 永远也存不到 localstorage 里了

是否可以提供一个方法,cookies.setNowTime('Sun, 04 Jun 2023 11:12:09 GMT'),由使用者自己去更新当前时间

当然这个方法也不够好,欢迎大家讨论呀

"vendor/weapp-cookie/src/set-cookie-parser.js" is not defined

错误信息:

VM27347:1 Error: module "vendor/weapp-cookie/src/set-cookie-parser.js" is not defined
at require (WAService.js:18)
at WAService.js:18
at Cookie.js? [sm]:1
at require (WAService.js:18)
at WAService.js:18
at CookieStore.js? [sm]:1
at require (WAService.js:18)
at WAService.js:18
at cookieShim.js? [sm]:1
at require (WAService.js:18)

app.js:

import './vendor/weapp-cookie/index'

项目结构:
image

大佬,我维系你小程序上传图片报错了

[publib]:1 thirdScriptError
Cannot read property 'Set-Cookie' of undefined;at api uploadFile success callback function
TypeError: Cannot read property 'Set-Cookie' of undefined
at options.success (weapp:///vendor/weapp-cookie/dist/weapp-cookie.js:2280:48)
at Function.function.o.(anonymous function) ([publib]:1:775794)
at [publib]:1:101961
at O ([publib]:1:226349)
at a. ([publib]:1:448535)
at a.emit ([publib]:1:239662)
at ca ([publib]:1:449069)
at [publib]:1:449744
at [publib]:1:254296
at Object.S ([publib]:1:1767)

小程序使用了插件,引入js报错了

我把dist目录下的weapp-cookie.js放到了我项目中的utils目录中,然后在app.js中引入了,就报错了。
我的小程序项目使用了插件,文档中说小程序插件的安全机制,不允许改写wx.request方法。
变通的方法是使用别名。但是现在我想让这个不报错。请问怎么让这个先不报错呀
image

image

接收到的cookie和传过去的cookie不一致

接收到的cookie是mXSPmPD_QGg9pwZpTnk-K6fw1qBtZAWW-8PdJMZ9zmbTGU-uHnQK5khGbiJZkHYcdWzj_0ysqJVQHm_8V6op8g==

但接下去get请求传过去的cookie是mXSPmPD_QGg9pwZpTnk-K6fw1qBtZAWW-8PdJMZ9zmbTGU-uHnQK5khGbiJZkHYcdWzj_0ysqJVQHm_8V6op8g%3D%3D

最后的两个==被转码了。

版本升级导致cookie不兼容问题【小程序】【原因已查明】

在我们的微信小程序版本里面用到了这个优秀的开源库。

我们的线上版本小程序使用了较为老的版本,不支持wx.request 返回值,由于业务需求,更新到了支持返回值的版本。
在测试回归的过程中发现以下问题
1、线上版本登录(老版本的cookie 库)
2、开发使用较为新版本的cookie库
此时小程序会给开线上版本的cookie storage里面的内容copy到开发版本里面
3、因此,此时开发版本具有cookie登录态
4、在开发版本(使用了较新的cookie库)执行一次业务的logout(未清理cookie storage)
5、出现登录问题
原因:未清理cookiestorage,老版本的domain使用的原值,而新版本使用的则是 .domain (注意前面的小数点)
之前的代码变更记录:
da3b65b#diff-551481066803574ad76d2485fe6c3b27c4800a1140c27d4a62a6d84442c9dde1R273


问题修正:
1、使用数据隔离策略,线上和线下使用不同的cookie storage key, 相当于给线上的cookie都暂时废了,用户都需要重新登录一遍。
2、在logout时同时清空对应的cookie

期望:
作为一个使用量比较多的库,有一个 release note之类的,提醒用户升级的注意事项。

[Bug Report] 源码中对responseCookies解析存在兼容问题

比如当Response Headers中存在多个Set-cookie时:

Set-Cookie: key1=value1; domain=/site; expires=Fri, 12-Jul-2019 01:37:01 GMT; path=/; secure
Set-Cookie: key2=value2; domain=/site; expires=Fri, 12-Jul-2019 01:37:01 GMT; path=/; secure

weapp-cookie.js源码第2400行中:

...

// 请求成功回调
      var successCallback = options.success;
      options.success = function (response) {
        response.header = response.header || response.headers;
        // 获取响应 cookies
        var responseCookies = response.header ? response.header['Set-Cookie'] || response.header['set-cookie'] : '';
        // 设置 cookies,以便下次请求带上
        if (responseCookies) cookieStore.setResponseCookies(responseCookies, domain);
        // 调用成功回调函数
        successCallback && successCallback(response);
      };

...

目前发现,在QQ小程序下,IOS设备正常,但安卓设备下读取的responseCookies格式与IOS设备不一致,导致后续一系列的parse等解析出现异常,造成安卓设备无法使用该库,原因如下:

IOS设备下调试QQ小程序,就以上headers数据来说,responseCookies返回的是:

"key1=value1; domain=/site; expires=Fri, 12-Jul-2019 01:37:01 GMT; path=/; secure,key2=value2; domain=/site; expires=Fri, 12-Jul-2019 01:37:01 GMT; path=/; secure"

注意:IOS下这里多个cookie之间是以逗号拼接的,这是正确的情况

而Android设备下调试QQ小程序,responseCookies返回的是:

"key1=value1; domain=/site; expires=Fri, 12-Jul-2019 01:37:01 GMT; path=/; secure;key2=value2; domain=/site; expires=Fri, 12-Jul-2019 01:37:01 GMT; path=/; secure"

注意:这里多个cookie之间的拼接和ios不一致,是以分号拼接,secure;key2=value2;

所以,需要在这里对responseCookies进行一个兼容处理,将分号替换成逗号,不然后续的parseStringsplitCookiesString都将无法返回正确的结果。

目前我的临时解决方案是在读取到responseCookies后,加上:

if (typeof responseCookies === 'string') {
   responseCookies = responseCookies.replace(/secure;/g, 'secure,');
}

但考虑到不一定是以secure结尾,所以要按情况来判断

PC端小程序不兼容

PC端小程序的header['Set-Cookie']和移动端有差异,解析出来的值对不上。

Cookie 中文

Cookie 包含中文时候, 微信小程序 开发工具提示。 request:fail Failed to execute 'setRequestHeader' on 'XMLHttpRequest': Value is not a valid ByteString.

客户端 并未操作 Cookie, Cookie 操作全在 服务器

在uni-app编译安卓端清除cookie的问题

uni-app在执行清除指定cookie操作后,小程序端cookie正常清除,安卓端也通过控制台打印cookie也应该清除了,但是在发起request请求时安卓app还是会携带已经被清除了的cookie,请问这个怎么整

希望可以配置关闭跨域传输cookie

现在我再A接口返回的
Set-Cookie: cookieName=xxxxxx; Domain=.a.com; Path=/

B接口是www.b.com:2443,无法上送cookieName;
代码里面应该有判断是否跨域上送cookie的配置,希望可以设置关闭,谢谢

发现这个文件解析有问题
/weapp-cookie/src/util.js

  getCookieScopeDomain (domain = '') {
    if (!domain) return []

    // 获取 cookie 作用域范围列表
    domain = domain.replace(/^\.+/ig, '')
    let scopes = domain.split('.').map(k => ['.', domain.slice(domain.indexOf(k))].join(''))

    return [domain].concat(scopes)
  }
# getCookieScopeDomain('www.baidu.com.cn:2443')
# ["bfiles-stg.pingan.com.cn:2443", ".bfiles-stg.pingan.com.cn:2443", ".pingan.com.cn:2443", ".com.cn:2443", ".cn:2443"]

端口号没去掉

cookies.get方法报错

_weappCookie2.default.get is not a function;at pages/web-view/index page lifeCycleMethod onLoad function
TypeError: _weappCookie2.default.get is not a function

domain的set规则问题和cookie编码问题

1、如 #14 所说,我也遇到了这个问题,但是我们原先web(微网页)情况下是没问题的,发现web环境时,后端返回的domain字段即使为:xxx.com,浏览器也会将其自动设置为 .xxx.com。但是你的规则与浏览器的不一样,所以带不上cookie。
2、我们的value中有@这个字符,发现被encode了,接收时和发送时不一致,发现了这个commit:e21617e 在发送时应该要decode啊,而且中文cookie值这个想不出来为什么会干这种事...是否编码也可以提供个选项出来啊

set-cookie max-age:0 不起作用

Cookie构造函数,在max-age为0时会赋值为null

constructor (props) {
    this.name = props.name || ''
    this.value = props.value || ''
    // other
    this.domain = props.domain || ''
    this.path = props.path || '/'
    this.expires = props.expires ? new Date(props.expires) : null
    // 这一行在max-age为0时会设为null
    this.maxAge = props.maxAge ? parseInt(props.maxAge) : null
    this.httpOnly = !!props.httpOnly
    // 记录时间
    this.dateTime = props.dateTime ? new Date(props.dateTime) : new Date()
  }

所以在判断是否过期的方法中,会返回默认false,导致cookie还会携带

     /**
   * 验证 cookie 是否还有效
   * @return {Boolean} 是否有效
   */
  isExpired () {
    // maxAge 为 0,无效
    if (this.maxAge === 0) {
      
      return true
    }
    // 存活秒数超出 maxAge,无效
    if (this.maxAge > 0) {
      let seconds = (Date.now() - this.dateTime.getTime()) / 1000
      return seconds > this.maxAge
    }
    // expires 小于当前时间,无效
    if (this.expires && this.expires < new Date()) {
      return true
    }
    return false
  }

读取到到cookie似乎不完整

实际操作的时候发现cookie不完整,少了一部分。我反复查看和修改了下面的代码,最终也没找到问题所在:

    let arr = setCookieStr.split(/\s*\\;\s*/g)
    arr.forEach((item, i) => {
      let temp = item.split('=')
      if (i === 0) {
        this.key = temp[0]
        this.value = temp[1]
      } else {
        let prop = temp[0]
        let value = temp[1]

我觉得应该是这段代码的问题。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.