flutterchina / cookie_jar Goto Github PK
View Code? Open in Web Editor NEWA cookie manager for http requests in Dart, by which you can deal with the complex cookie policy and persist cookies easily.
License: MIT License
A cookie manager for http requests in Dart, by which you can deal with the complex cookie policy and persist cookies easily.
License: MIT License
FileSystemException: Exists failed, path = '/C:/Users/xxx/Documents/.cookies/ie0_ps1/' (OS Error: 文件名、目录名或卷标语法不正确。
, errno = 123)
FileStorage.init (file_storage.dart:42)
PersistCookieJar._checkInitialized (persist.dart:49)
PersistCookieJar.loadForRequest (persist.dart:106)
Flutter 3.10.6
cookie_jar: 4.0.7
I delete recursively the 'cookies" directory that my app created, then instantiate PersistCookieJar again with the same directory name, but the cookies are still remembered after such "clear cookies" call, until the app is exited and restarted.
Probably some static variable has all the cookies previously read saved? Please add PersistCookieJar.clearCookies() method or something similar.
Greg
There is No FileLock of the method delete, deleteAll, read, read of FileStorage in file file_storage.dart Will be exception dio On concurrency request .
https://stackoverflow.com/questions/21924211/how-to-lock-a-file-for-writing-in-dart
By the reason of internal error inside PersistCookieJar class (type '_Map<dynamic, dynamic>' is not a subtype of type 'Map<String, Map<String, SerializableCookie>>') all cookies deleted when application is starting
#0 PersistCookieJar._checkInitialized.<anonymous closure> (package:cookie_jar/src/persist_cookie_jar.dart:73:13)
#1 MapBase.map (dart:collection/maps.dart:82:28)
#2 PersistCookieJar._checkInitialized (package:cookie_jar/src/persist_cookie_jar.dart:54:32)
<asynchronous suspension>
#3 PersistCookieJar.loadForRequest (package:cookie_jar/src/persist_cookie_jar.dart:99:5)
<asynchronous suspension>
...
str value from file:
{"dateamillionaire.com.pilot":{"/":{"ps_v2_local_session":"ps_v2_local_session=0f4een5vd4ttjb0iqmbvjmnfbi; Domain=dateamillionaire.com.pilot; Path=/;_crt=1685113197","pc_v1_local_lang":"pc_v1_local_lang=en; Expires=Sat, 29 Apr 2028 14:59:57 GMT; Max-Age=155520000; Domain=dateamillionaire.com.pilot; Path=/;_crt=1685113197"}}}
I think the condition on this line is not true: https://github.com/flutterchina/cookie_jar/blame/a14f284ba731fc2e69bd940770b182adb2659781/lib/src/jar/persist.dart#L133
final isSession = cookie.cookie.expires == null && cookie.cookie.maxAge == null;
if ((isSession && persistSession) || (persistSession && !cookie.isExpired())) {
return MapEntry(key, cookie);
} else {
return MapEntry(null, cookie);
}
Why should persistSession
be true to save cookies that are not session cookies and not expired ? This condition implies, one should should store all cookies including session cookies, or none at all.
4.0.2
这几天我更新了 CookieJar 到最新版本。跨版本更新的问题我已经解决,但是我之前写的登录逻辑用不了了。
经过我抓包,我发现很多必要的 Cookie 并没有送过去,然后我查看了 Cookie Jar 的代码,发现确实如此。
以下是我添加了很多 print 函数的 Cookie Jar loadForRequest 代码:
Future<List<Cookie>> loadForRequest(Uri uri) async {
print("From cookie_jar loadForRequest, url is $uri");
final list = <Cookie>[];
final urlPath = uri.path;
// Load cookies without "domain" attribute, include port.
print("From cookie_jar loadForRequest, urlPath is $urlPath");
final hostname = uri.host;
print("From cookie_jar loadForRequest, hostName is $hostname");
for (final domain in hostCookies.keys) {
if (hostname == domain) {
final cookies =
hostCookies[domain]!.cast<String, Map<String, dynamic>>();
print("From cookie_jar loadForRequest, cookies are $cookies");
// Sort by best match (longer path first)
final keys = cookies.keys.toList()
..sort((a, b) => b.length.compareTo(a.length));
print("From cookie_jar loadForRequest, keys is $keys");
for (final path in keys) {
print("From cookie_jar loadForRequest, cur. path is $path");
if (_isPathMatch(urlPath, path)) {
final values = cookies[path]!;
print("From cookie_jar loadForRequest, path above match");
for (final key in values.keys) {
final SerializableCookie cookie = values[key];
print("From cookie_jar loadForRequest, cur. cookie is $cookie");
if (_check(uri.scheme, cookie)) {
print("From cookie_jar loadForRequest, added ${cookie.cookie}");
// preserve cookies that with same name but in different paths when request (as Chrome);
// eg(in request header): Cookie: a=1; a=2; a=3
list.add(cookie.cookie);
}
}
}
}
}
}
执行时候的输出结果如下:
flutter: From cookie_jar loadForRequest, cur. path is /xsfw/sys/xszsapp/commoncall/callQuery
flutter: From cookie_jar loadForRequest, path above match
flutter: From cookie_jar loadForRequest, cur. cookie is route=f1b4659eb550ac78a3aba9159e08a2ad;_crt=1684566347
flutter: From cookie_jar loadForRequest, added route=f1b4659eb550ac78a3aba9159e08a2ad
flutter: From cookie_jar loadForRequest, cur. path is /xsfw/sys/xszsapp/*default
flutter: From cookie_jar loadForRequest, cur. path is /personalinfo
flutter: From cookie_jar loadForRequest, cur. path is /authserver
flutter: From cookie_jar loadForRequest, cur. path is /jsonp
flutter: From cookie_jar loadForRequest, cur. path is /xsfw/
flutter: From cookie_jar loadForRequest, cur. path is /
flutter: From cookie_jar loadForRequest, path above match
flutter: From cookie_jar loadForRequest, cur. cookie is MOD_AUTH_CAS=MOD_AUTH_ST-406717-P1JJoYnb-tM-vlkL1DRMeY5nhgcauthserver6; Path=/; HttpOnly;_crt=1684566346
flutter: From cookie_jar loadForRequest, added MOD_AUTH_CAS=MOD_AUTH_ST-406717-P1JJoYnb-tM-vlkL1DRMeY5nhgcauthserver6; Path=/; HttpOnly
flutter: From cookie_jar loadForRequest, cur. cookie is asessionid=70957866-5e03-4573-8202-1f77abf3ecb8; Path=/;_crt=1684566346
flutter: From cookie_jar loadForRequest, added asessionid=70957866-5e03-4573-8202-1f77abf3ecb8; Path=/
flutter: From cookie_jar loadForRequest, cur. cookie is JSESSIONID=B2Q4IpE_HcUNPAYg89lwHxYS2-oe4prAJR8pB060TW_dwATkWp2Z!-1260680682; Path=/; HttpOnly;_crt=1684568969
flutter: From cookie_jar loadForRequest, added JSESSIONID=B2Q4IpE_HcUNPAYg89lwHxYS2-oe4prAJR8pB060TW_dwATkWp2Z!-1260680682; Path=/; HttpOnly
flutter: From cookie_jar loadForRequest, cur. path is
flutter: From cookie_jar loadForRequest, path above match
flutter: From cookie_jar loadForRequest, cur. cookie is route=efe65af6112e14c9eee4f9e623e0f16d;_crt=1684566346
flutter: From cookie_jar loadForRequest, added route=efe65af6112e14c9eee4f9e623e0f16d
flutter: Here are the cookies: [route=f1b4659eb550ac78a3aba9159e08a2ad, MOD_AUTH_CAS=MOD_AUTH_ST-406717-P1JJoYnb-tM-vlkL1DRMeY5nhgcauthserver6; Path=/; HttpOnly, asessionid=70957866-5e03-4573-8202-1f77abf3ecb8; Path=/, JSESSIONID=B2Q4IpE_HcUNPAYg89lwHxYS2-oe4prAJR8pB060TW_dwATkWp2Z!-1260680682; Path=/; HttpOnly, route=efe65af6112e14c9eee4f9e623e0f16d]
// 接下来报 403 无权限访问
跟据我请求的地址,应该是匹配 /xsfw
下面的很多东西,然而这里只有 /xsfw/sys/xszsapp/*default
被匹配。剩下的 /xsfw/sys/xszsapp/*default
/xsfw/
没有被匹配。之前我研究,必须需要这两个里面的 Cookie 才能执行。
不知道这是本程序的 Bug 还是我对 Cookie 的理解有啥偏差,辛苦维护者了。
Hi,
Could you please export the Cookie out from the package:universal_io package?
Otherwise, we have to import the package explicitly, and maintain the same version with this.
Thanks.
It took me a while to figure this out, but the default Cookie Jar uses a static list of cookies. Two instances of the CookieJar will reuse the same memory, which is really surprising and unexpected behavior.
In my case, I have two test dio clients where I do not want to share cookies between the two clients.
consumers of cookieJar can always create a single instance if they really want a single global cookie store.
import 'package:cookie_jar/src/stroage.dart';这个地方应该是 storage,不是stroage
I'd like to read/write cookies from default_cookie_jar, but I have to explicitly reference the file
import 'package:cookie_jar/src/default_cookie_jar.dart';
instead of referencing just the package
import "package:cookie_jar/cookie_jar.dart";
It works, but then dart yields a warning not to reference files from packages directly.
"Cookie" no longer seems to exist. The documentation for this plugin should be updated to reflect this change and an example of how to use the plugin should be added.
In Android, a flutter app can run multiple times in another task or app.
If one changes cookies it will save into file, but another apps won't know it and they cannot reload it from file because it is already cached in static variable.
I resolved it by adding a function that invalidate the static variable like following, but hope there's an official way to deal with it.
void forceInit() {
_dirInit[_dir] = null;
_checkInited();
}
FileSystemException: FileSystemException: Deletion failed, path = '/data/user/0/com.example.app/app_flutter/.cookies/ie0_ps1/'
(OS Error: No such file or directory, errno = 2)
Crashed in non-app: directory_impl.dart in _Directory._delete.
file_storage.dart in FileStorage.deleteAll at line 30 within cookie_jar
persist_cookie_jar.dart in PersistCookieJar.deleteAll at line 165 within cookie_jar
Hi,
When calling loadForRequest
I'm getting cookies that were expired long before even initializing PersistCookieJar
with FileStorage
.
I was looking into the code and found in PersistCookieJar
that the _filter
method that seems responsible for filtering expired cookies is only called on _save
but not on _load
.
Is this an expected behavior? I'm thinking about submitting a PR about this, but wanted to make sure that I was heading to the right direction.
Thanks
In the DefaultCookieJar
class, cookies are saved in a private member _domains
, which is currently static
, meaning all DefaultCookieJar
instances share the same cookie storage.
Is there any reason behind this decision or is it a bug? Seems like a potential security vulnerability to me.
I wonder if cookies are encrypted in case of PersistCookieJar or not?
根据 RFC6265 4.1.2.4,当服务端 Set-Cookie 字段缺失 Path 时,应该使用当前页面的“目录”作为默认的 cookie 路径。也就是说,如果 URI 为 /w/login
,那么 Cookie 的路径应该为 /w/
。
According to RFC6265 4.1.2.4, user agent uses the "directory" of request-uri as default path if there is no 'Path' component in Set-Cookie
line. In that way, if the URI is /w/login
,the path of cookie will be /w/
by default.
但是在 cookie_jar 3.0.1 版本中,default_cookie_jar.dart 文件的 saveFromResponse
函数:
But in version 3.0.1 of cookie_jar
, in method saveFromResponse
, default_cookie_jar.dart.
@override
Future<void> saveFromResponse(Uri uri, List<Cookie> cookies) async {
for (final cookie in cookies) {
var domain = cookie.domain;
String path;
var index = 0;
// Save cookies with "domain" attribute
if (domain != null) {
if (domain.startsWith('.')) {
domain = domain.substring(1);
}
path = cookie.path ?? '/';
} else {
index = 1;
// Save cookies without "domain" attribute
// 注意,问题出在这里. NOTICE HERE.
path = cookie.path ?? (uri.path.isEmpty ? '/' : uri.path);
domain = uri.host;
}
var mapDomain =
_cookies[index][domain] ?? <String, Map<String, dynamic>>{};
mapDomain = mapDomain.cast<String, Map<String, dynamic>>();
final map = mapDomain[path] ?? <String, dynamic>{};
map[cookie.name] = SerializableCookie(cookie);
if (_isExpired(map[cookie.name])) {
map.remove(cookie.name);
}
mapDomain[path] = map.cast<String, SerializableCookie>();
_cookies[index][domain] =
mapDomain.cast<String, Map<String, SerializableCookie>>();
}
}
默认使用了 uri.path
,和预期及浏览器行为不一致。这导致了我的爬虫出了点问题……
The method uses uri.path
which does in a different way with browsers. So my crawler crashed...
Directory tempDir = await getTemporaryDirectory();
String tempPath = tempDir.path;
CookieJar cj=new PersistCookieJar(tempPath);
cj.deleteAll()
//got an error on iOS device iPhone 8 iOS 12.1.1
error: (OS Error: Permission denied, errno = 1)
But it works fine on the simulator & I don't know if Android is the same.
If cookie is set for https://sub1.domain.com
it should be also loaded for https://sub2.domain.com
(as described in https://tools.ietf.org/html/rfc6265#section-4.1.2.3). Now DefaultCookieJar is not working this way.
Previously, my app successfully manages session which uses cookie using this simple piece of configuration (other unrelated codes are truncated)
final cookieJar = PersistCookieJar(
storage: FileStorage(directory.path + '/.cookies'),
);
dio.interceptors.add(CookieManager(cookieJar));
But now, the cookie fails to be automatically set to the request header after migrating to these versions, even though I don't change any code related to Dio's setups.
cookie_jar: ^4.0.2
dio: ^5.1.1
dio_cookie_manager: ^3.0.0
If I manually injected a valid cookie to the header, my backend can authenticate the request successfully. It means, the bug is either one or more of those new libraries, failing to set the cookie automatically
This issue might be related to #41 , but not entirely sure because I can't understand the language.
Thank you.
When I try to compile and run my project that depends on cookie_jar
, it fails to build with the following error:
Launching lib/main.dart on Chrome in debug mode...
main.dart:1
: Error: Can't assign spread elements of type 'Cookie/*1*/' to collection elements of type 'Cookie/*2*/'.
cookie_mgr.dart:58
- 'Cookie/*1*/' is from 'package:cookie_jar/src/cookie/_cookie_web.dart' ('../../../.pub-cache/hosted/pub.dev/cookie_jar-4.0.1/lib/src/cookie/_cookie_web.dart').
_cookie_web.dart:1
- 'Cookie/*2*/' is from 'dart:_http'.
...cookies,
^
: Error: The argument type 'List<Cookie/*1*/>' can't be assigned to the parameter type 'List<Cookie/*2*/>'.
cookie_mgr.dart:122
- 'List' is from 'dart:core'.
- 'Cookie/*1*/' is from 'dart:_http'.
- 'Cookie/*2*/' is from 'package:cookie_jar/src/cookie/_cookie_web.dart' ('../../../.pub-cache/hosted/pub.dev/cookie_jar-4.0.1/lib/src/cookie/_cookie_web.dart').
_cookie_web.dart:1
await cookieJar.saveFromResponse(response.realUri, cookies);
^
: Error: The argument type 'List<Cookie/*1*/>' can't be assigned to the parameter type 'List<Cookie/*2*/>'.
cookie_mgr.dart:130
- 'List' is from 'dart:core'.
- 'Cookie/*1*/' is from 'dart:_http'.
- 'Cookie/*2*/' is from 'package:cookie_jar/src/cookie/_cookie_web.dart' ('../../../.pub-cache/hosted/pub.dev/cookie_jar-4.0.1/lib/src/cookie/_cookie_web.dart').
_cookie_web.dart:1
cookies,
^
Failed to compile application.
Exited
Any idea why?
I noticed the docs mention that it can be compiled on web.
为什么没有中文文档
code
final Directory appDocDir = await getTemporaryDirectory();
final String appDocPath = appDocDir.path;
final cookieJar=PersistCookieJar(
storage: FileStorage(appDocPath)
);
File file=File(appDocPath);
await file.create();
log("call getApi");
String url_is = "$baseUrl/$url";
log("url is $url_is");
dio.interceptors.add(CookieManager(cookieJar));
var response = await dio.get("$baseUrl/$url");
log(response.data.toString());
FileSystemException: Cannot open file, path = '/data/user/0/com.example.eyebase_api_call/cache/ie0_ps1/' (OS Error: Is a directory, errno = 21)
The delete
and deleteAll
functions are not in the abstract class for CookeJar, so they cannot be called from a new CookieJar()
instance.
i.e., this does not work:
var c = new CookieJar();
c.deleteAll();
Also, please provide a way to delete an individual cookie value from a domain, as in:
cookie.delete("mydomain", "mycookiename");
你好,目前在使用cookiejar与dio配合时,设置cookirJar出现如下错误提示:The setter 'cookieJar' isn't defined for the class 'Dio'.
各依赖版本 (Packages' Version):
cookie_jar: ^1.0.0
dio: ^2.1.0
代码 (Code) :
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:cookie_jar/cookie_jar.dart';
class NetUtils {
static Future<String> get(String url, queryParameters) async {
Dio dio = new Dio();
dio.cookieJar = new PersistCookieJar(dir:"./cookies");
Response response = await dio.get(url);
return response.toString();
}
}
Does it support for web?
The current Dart SDK version is 2.1.0-dev.0.0.flutter-be6309690f.
Because dio <0.1.1 requires SDK version >=1.20.1 <2.0.0 and dio >=0.1.1 depends on cookie_jar ^0.0.4, every version of dio requires cookie_jar ^0.0.4.
So, because cookie_jar >=0.0.2 requires SDK version >=1.20.1 <2.0.0 and downloader depends on dio any, version solving failed.
I think lib should option for cookies storage. So as programmer may choose to store cookies in either files or using libs like shared_preference or flutter_secure_storage.
If this sounds good to you maybe I could open PR.
I can't access the Cookie
class, as it's private. Therefore, I can't override any methods.
python的cookie在处理是有两个参数可以控制:
ignore_discard: save even cookies set to be discarded.
ignore_expires: save even cookies that have expiredThe file is overwritten if it already exists
ignore_discard的意思是即使cookies将被丢弃也将它保存下来
ignore_expires的意思 是如果cookies已经过期也将它保存并且文件已存在时将覆盖
不知道库里可以加这两个逻辑吗?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.