https://www.youtube.com/watch?v=mVEItYOsXjM&feature=youtu.be&fbclid=IwAR0u5kh2T7HtQdmXZO-d72IoZAfrZZ3-BJnFMDdKTjvgvIYmoGOZBLM1Aj0
1、拿出大陸和早期的新聞來做說明,請問之前蔡總統的狗上新聞,各媒體都有報導,過了二十、三十年後,有人把這些剪在一起,也報導出來,告訴大家蔡總統是一個重視狗,不重視人民,這媒體是不是有問題?在客觀表達上就有問題了
而且還扣上每一間媒體都要聽話?!單單看到這就已經代表公視在沉淪了!一個有客觀公正的人看到這段馬上就要會質疑,它怎麼扣上每一個媒體!另外拿一些國家大事來論就更可笑,試例台灣買美國武器,全台灣媒體都有報導,所以全部的媒體都是官媒囉?這種例子100%肯定邏輯是不通的,為什麼不通?因為內容不見得支持啊!正反的意見從各自媒體支持方向不同而改變內容,這才是公平。
其實這種Youtube我是真的不想看,看了第一段隨便思考一下就能發現一堆問題…
正確報導這種話題本來就不容易,更應該收集齊全資料做展示,剪接也要注意避免產生不公平情況,80%主流意見,20%非主流意見,在同一個時間內報導,是否會造成好像是50% 50%的情況
試思考一下,現在誰不支持蔣中正,我敢說 拿到現今社會,年輕人都支持蔣中正力抗 “中國共產黨“,真正發展軍備跟“中國共產黨“打一仗:多想想這種很奇怪的思想轉換,多想想這個試問吧
請問像youtube這種報導越多,拿著公正當口號,細節到處都是不公正,看越多又不思考,越被洗惱
2、拿財團來當例子… 上面說政府要退出媒體,這裡討論財團買媒體,假設財團不買媒體,媒體怎麼生存,誰要買?嗯,有人提到那就定下法律媒體必OOXX來保障,這有腦嗎?多想想這件事,就會發現這又是一個很可笑的答案
a. TVBS炒HTC
b. 三立炒牧場
請問別家媒體會跟TVBS、三立一起炒嗎?這又扯到另一個買報導問題
一個獨立思考,有公正能力判斷的人,看媒體只看一家,一直看一家報導??!!只看自己喜歡看的?那他怎麼會認為自己是有公正能力判斷的人?假如他看了多家媒體,自然怎麼會被洗腦??!!是自己願意被洗還是怪別人來洗?
這些非常簡單,思考一下,就能得到論述及答案,這支影片怎麼都沒提到,看到這裡,這支影片和它的標題已經漸行漸遠了
3、直接點明旺旺,齊下有很多媒體,播一段董事長的話,我聽了覺得一點問題都沒有,做大陸的生意,當然會說大陸好話,這是表裡如一啊!難道有人期望賺大陸的錢,還要罵大陸,要成為表裡不一的人!要我們整個社會文化成為表裡不一的人?!!
回到2. 你可以看很多媒體啊!
每個人都可以支持統一,支持台獨,有錢的人寫書、辨報、經營媒體、做youtube影片、直播等等,越多人可以表達出來,公正客觀的人就能從中接收到不同的訊息,其中思考
4、拿佔中來論,回到1吧,1在說所有媒體都在報導同一件事,是官媒! 哈,思考一下,這支影不就正在做 “把媒體綁架“,拿 來綁架嗎
旺旺覺得佔中不支持,改報導其他覺得更重要的事,那是它的自由啊!而其他一堆報紙要報導,那也是它的自由啊!
另外再用邏輯思考一下,同樣的“佔中“是誰在洗腦?!所有的媒體都在報導“佔中“,是除了旺旺外,沒在洗你我的腦。
再請問一下,旺旺只佔了一部份媒體吧,那他又怎麼洗腦? 試想 我說某集團洗腦,結果這集團還只佔全部的20%…… 我都無言了
這影片....................真正思考的人都知道他在幹什麼事,拿口號、流行來做 。
5、誰說沒了這些媒體就黑暗了…… 鬼扯什麼 人跟人面對面交流更重,流言就沒有了嗎?
6、誰說台灣媒體只有報導中國的好處?自由獨派死光了,誰說台灣媒體只有報導中國的壞處?統一派死光了!早就有兩派人馬互鬥,這影片用很感性的話:沒有… 照不到…
早就有了啦!在鬼扯什麼啊!另外拿國外媒體也請同樣拿出國外媒體支持中共的報導…看到這裡我在想
做這影片的人,心中早有定見,看到一邊,在說一邊的不足,卻故意忽略明明早就有另一邊的報導
穆斯林照不到,爭眼說瞎話!照不到會“一堆國外媒體爭相報導“ ,影片作者你會知道??!! 你到底在說什麼鬼話啊!
7、請問失去照不到,綠營一堆都在討論,在告訴民眾,影片作者到底你在爭眼說瞎話,說什麼鬼?!三立、自由被現在政府打壓,負責人被國安法送辨,秘密審判、刑求,家人被查水表,沒工作,小孩在校被打被罵?!
還是NCC要求三立、自由不準報導,撤照??!!
當你用感性的語氣說這種話時,你是在用什麼說服,用公正客觀的媒體權,還是自我的意識
整個影片真慘……啊!只有強調不要被中共洗腦,而不是談怎麼避免媒體洗腦
沒有提到提到任何 “要思考“ “要多看“,也沒有提到 “去掉情緒用語“
當用公視的名義時,心中的正義到那去了
https://youtu.be/3lJzka7IKDE?t=1147 小董真心話裡面提到的頂新,最近觀察新聞真的是這樣啊!!!
capacitor barcode scan
If you npm install a Cordova/Capacitor plugin after npx cap add android then make sure you run npx cap update before running from Android Studio again.
If you make html, js, ts, css changes, run ionic build again and also run npx cap copy.
Or when in doubt, run npx cap sync as it does update+copy.
https://github.com/ionic-team/capacitor/issues/1213
https://stackoverflow.com/questions/23060038/cant-use-barcode-scanner-in-cordova-plugin-is-installed
1. init
2. npm i phonegap-plugin-barcodescanner
3. modify www/index.html
ADD
If you make html, js, ts, css changes, run ionic build again and also run npx cap copy.
Or when in doubt, run npx cap sync as it does update+copy.
https://github.com/ionic-team/capacitor/issues/1213
https://stackoverflow.com/questions/23060038/cant-use-barcode-scanner-in-cordova-plugin-is-installed
1. init
npx @capacitor/cli create testbarcode
npx cap add android
npx cap sync
npx cap copy
npx cap open android
ctrl+c exit
2. npm i phonegap-plugin-barcodescanner
npm i phonegap-plugin-barcodescanner --save
npx cap sync
npx cap copy
3. modify www/index.html
ADD
<button onclick="myFunction2()">Try it barcode</button>
<script>
async function myFunction2() {
cordova.plugins.barcodeScanner.scan(
result => console.log(result),
err => console.error(err),
{
showTorchButton: true,
prompt: "Scan your code",
formats: "QR_CODE",
resultDisplayDuration: 0
}
);
}
</script>
npx cap sync
npx cap copy
android studio run
PS: use cordova.plugins NOT window.cordova.plugins
siege
http://xstarcd.github.io/wiki/shell/siege.html
https://coder.tw/?p=7198
==========
很像REST Client
1. var = 兩邊不能有空白
EX:
@9020_login = http://192.168.99.100:9020/login
9020_login=http://192.168.99.100:9020/login
2. 當有空白行時
EX:
@_csrf1 = Gxa6Hip4-J_A3L2kpRc72Iclw_Ql8eIcQiTc
@login_challenge = 394bab045e2e4a25be83fe207440787e
如果login_chanllenge是最後一個參數,要補上&
_csrf1=Gxa6Hip4-J_A3L2kpRc72Iclw_Ql8eIcQiTc
login_challenge=394bab045e2e4a25be83fe207440787e&
siege會把CR當成參數內容傳送
==========
siege --help
SIEGE 3.0.6
Usage: siege [options]
siege [options] URL
siege -g URL
Options:
-V, --version VERSION, prints the version number.
-h, --help HELP, prints this section.
-C, --config CONFIGURATION, show the current config.
#在屏幕上打印显示出当前的配置,配置是包括在他的配置文件$HOME/.siegerc中,
#可以编辑里面的参数,这样每次siege 都会按照它运行.
-v, --verbose VERBOSE, prints notification to screen.
#运行时能看到详细的运行信息
-q, --quiet QUIET turns verbose off and suppresses output.
-g, --get GET, pull down HTTP headers and display the
transaction. Great for application debugging.
-c, --concurrent=NUM CONCURRENT users, default is 10
#模拟有n个用户在同时访问,n不要设得太大,因为越大,siege 消耗本地机器的资源越多
-i, --internet INTERNET user simulation, hits URLs randomly.
#随机访问urls.txt中的url列表项,以此模拟真实的访问情况(随机性)
-b, --benchmark BENCHMARK: no delays between requests.
-t, --time=NUMm TIMED testing where "m" is modifier S, M, or H
ex: --time=1H, one hour test.
#持续运行siege ‘n’秒(如10S),分钟(10M),小时(10H)
-r, --reps=NUM REPS, number of times to run the test.
#重复运行测试n次,不能与 -t同时存在
-f, --file=FILE FILE, select a specific URLS FILE.
#指定用urls文件,默认为siege安装目录下的etc/urls.txt
#urls.txt文件:是很多行待测试URL的列表以换行符断开,格式为:
#[protocol://]host.domain.com[:port][path/to/file]
-R, --rc=FILE RC, specify an siegerc file
#指定用特定的siege配置文件来运行,默认的为$HOME/.siegerc
-l, --log[=FILE] LOG to FILE. If FILE is not specified, the
default is used: PREFIX/var/siege.log
#运行结束,将统计数据保存到日志文件siege.log中,可在.siegerc中自定义日志文件
-m, --mark="text" MARK, mark the log file with a string.
-d, --delay=NUM Time DELAY, random delay before each requst
between 1 and NUM. (NOT COUNTED IN STATS)
#hit每个url之间的延迟,在0-n之间
-H, --header="text" Add a header to request (can be many)
-A, --user-agent="text" Sets User-Agent in request
-T, --content-type="text" Sets Content-Type in request
** SIEGE 2.72
** Preparing 300 concurrent users for battle.
The server is now under siege.. done.
Transactions: 30000 hits #完成30000次处理
Availability: 100.00 % #成功率
Elapsed time: 68.59 secs #总共使用时间
Data transferred: 817.76 MB #共数据传输 817.76 MB
Response time: 0.04 secs #响应时间,显示网络连接的速度
Transaction rate: 437.38 trans/sec #平均每秒完成 437.38 次处理
Throughput: 11.92 MB/sec #平均每秒传送数据
Concurrency: 17.53 #实际最高并发连接数
Successful transactions: 30000 #成功处理次数
Failed transactions: 0 #失败处理次数
Longest transaction: 3.12 #每次传输所花最长时间
Shortest transaction: 0.00 #每次传输所花最短时间
https://coder.tw/?p=7198
==========
很像REST Client
1. var = 兩邊不能有空白
EX:
@9020_login = http://192.168.99.100:9020/login
9020_login=http://192.168.99.100:9020/login
2. 當有空白行時
EX:
@_csrf1 = Gxa6Hip4-J_A3L2kpRc72Iclw_Ql8eIcQiTc
@login_challenge = 394bab045e2e4a25be83fe207440787e
如果login_chanllenge是最後一個參數,要補上&
_csrf1=Gxa6Hip4-J_A3L2kpRc72Iclw_Ql8eIcQiTc
login_challenge=394bab045e2e4a25be83fe207440787e&
siege會把CR當成參數內容傳送
==========
siege --help
SIEGE 3.0.6
Usage: siege [options]
siege [options] URL
siege -g URL
Options:
-V, --version VERSION, prints the version number.
-h, --help HELP, prints this section.
-C, --config CONFIGURATION, show the current config.
#在屏幕上打印显示出当前的配置,配置是包括在他的配置文件$HOME/.siegerc中,
#可以编辑里面的参数,这样每次siege 都会按照它运行.
-v, --verbose VERBOSE, prints notification to screen.
#运行时能看到详细的运行信息
-q, --quiet QUIET turns verbose off and suppresses output.
-g, --get GET, pull down HTTP headers and display the
transaction. Great for application debugging.
-c, --concurrent=NUM CONCURRENT users, default is 10
#模拟有n个用户在同时访问,n不要设得太大,因为越大,siege 消耗本地机器的资源越多
-i, --internet INTERNET user simulation, hits URLs randomly.
#随机访问urls.txt中的url列表项,以此模拟真实的访问情况(随机性)
-b, --benchmark BENCHMARK: no delays between requests.
-t, --time=NUMm TIMED testing where "m" is modifier S, M, or H
ex: --time=1H, one hour test.
#持续运行siege ‘n’秒(如10S),分钟(10M),小时(10H)
-r, --reps=NUM REPS, number of times to run the test.
#重复运行测试n次,不能与 -t同时存在
-f, --file=FILE FILE, select a specific URLS FILE.
#指定用urls文件,默认为siege安装目录下的etc/urls.txt
#urls.txt文件:是很多行待测试URL的列表以换行符断开,格式为:
#[protocol://]host.domain.com[:port][path/to/file]
-R, --rc=FILE RC, specify an siegerc file
#指定用特定的siege配置文件来运行,默认的为$HOME/.siegerc
-l, --log[=FILE] LOG to FILE. If FILE is not specified, the
default is used: PREFIX/var/siege.log
#运行结束,将统计数据保存到日志文件siege.log中,可在.siegerc中自定义日志文件
-m, --mark="text" MARK, mark the log file with a string.
-d, --delay=NUM Time DELAY, random delay before each requst
between 1 and NUM. (NOT COUNTED IN STATS)
#hit每个url之间的延迟,在0-n之间
-H, --header="text" Add a header to request (can be many)
-A, --user-agent="text" Sets User-Agent in request
-T, --content-type="text" Sets Content-Type in request
** SIEGE 2.72
** Preparing 300 concurrent users for battle.
The server is now under siege.. done.
Transactions: 30000 hits #完成30000次处理
Availability: 100.00 % #成功率
Elapsed time: 68.59 secs #总共使用时间
Data transferred: 817.76 MB #共数据传输 817.76 MB
Response time: 0.04 secs #响应时间,显示网络连接的速度
Transaction rate: 437.38 trans/sec #平均每秒完成 437.38 次处理
Throughput: 11.92 MB/sec #平均每秒传送数据
Concurrency: 17.53 #实际最高并发连接数
Successful transactions: 30000 #成功处理次数
Failed transactions: 0 #失败处理次数
Longest transaction: 3.12 #每次传输所花最长时间
Shortest transaction: 0.00 #每次传输所花最短时间
nightwatch OpenID Hydra Windows
Windows
Update chrome v75
> mkdir t
> cd t
> midir tests
> npm install nightwatch --save-dev
> npm install chromedriver --save-dev
> nano nightwatch.js
require('nightwatch/bin/runner.js');
> nano nightwatch.conf.js
const chrome = require('chromedriver')
module.exports = {
src_folders: ['tests'],
webdriver: {
start_process: true,
server_path: chrome.path,
port: 9515,
},
test_settings: {
default: {
desiredCapabilities: {
browserName: 'chrome',
},
},
},
}
> nano tests/test.js
module.exports = {
'step one: navigate to google' : function (browser) {
for (var i = 0; i < 10; i += 1) {
browser
.url('https://t.tt:9010')
.waitForElementVisible('body', 1000)
.click('a')
.waitForElementVisible('input[type=email]')
.setValue('input[type=email]', 'foo@bar.com')
.setValue('input[type=password]', 'foobar')
.click('input[type=submit]', function(result) {
this.assert.strictEqual(result.status, 0);
})
.waitForElementVisible('input[type=checkbox]')
.click('input[id=openid]')
.click('input[id=offline]')
.click('input[id=accept]', function(result) {
this.assert.strictEqual(result.status, 0);
})
}
},
};
> node nightwatch.js tests/test.js
OpenID Hydra session data can't show at userinfo or introspect
If you use consent website(official login&consent) run all step, routes/consent.js session part need remove mark, surely you can get session data.
@token= xLPcJ3tobDqGUDxIVTxWt2p7w_odZSV22IAlUf5QPZU.YD6R_xKQ2ldCLbEV7mmc01E6ZLzemzdEC5H4-otTMPg
### userinfo
GET https://openid.hydra:9001/userinfo
Authorization: Bearer {{token}}
### introspect
POST https://openid.hydra:9002/oauth2/introspect
Content-Type: application/x-www-form-urlencoded
token={{token}}
&scope=openid+photos.read
PS:&scope=openid+photos.read can remove.
But you use REST Client need fix. Put session data by yourself.
### accept conent scope
PUT https://192.168.99.100:9002/oauth2/auth/requests/consent/accept?consent_challenge={{consent_challenge}}
Content-Type: application/json
{
"grant_scope": ["openid", "photos.read"],
"session": {
"access_token": { "foo": "bar" },
"id_token": { "baz": "bar" }
}
}
OpenID hydra
https://www.ory.sh/docs/next/hydra/oauth2#oauth-20-scope
A OAuth 2.0 Scope is not a permission:
A permission allows an actor to perform a certain action in a system: Bob is allowed to delete his own photos.
OAuth 2.0 Scope implies that an end-user granted certain privileges to a client: Bob allowed the OAuth 2.0 Client to delete all users.
The OAuth 2.0 Scope can be granted without the end-user actually having the right permissions. In the examples above, Bob granted an OAuth 2.0 Client the permission ("scope") to delete all users in his name. However, since Bob is not an administrator, that permission ("access control") is not actually granted to Bob. Therefore any request by the OAuth 2.0 Client that tries to delete users on behalf of Bob should fail.
我授權程式可以“讀取、刪除“權限,但實際上授權程式能不能真正“讀取、刪除“資料 或是 真正有“讀取、刪除“權限 是不一定有的
A OAuth 2.0 Scope is not a permission:
A permission allows an actor to perform a certain action in a system: Bob is allowed to delete his own photos.
OAuth 2.0 Scope implies that an end-user granted certain privileges to a client: Bob allowed the OAuth 2.0 Client to delete all users.
The OAuth 2.0 Scope can be granted without the end-user actually having the right permissions. In the examples above, Bob granted an OAuth 2.0 Client the permission ("scope") to delete all users in his name. However, since Bob is not an administrator, that permission ("access control") is not actually granted to Bob. Therefore any request by the OAuth 2.0 Client that tries to delete users on behalf of Bob should fail.
我授權程式可以“讀取、刪除“權限,但實際上授權程式能不能真正“讀取、刪除“資料 或是 真正有“讀取、刪除“權限 是不一定有的
OpenID hydra context data save
hydra login consent node
https://github.com/ory/hydra-login-consent-node
When login success, context data be saved .
Can use
GET https://openid.hydra:9002/oauth2/auth/sessions/consent?subject=foo@bar.com HTTP/1.1
check by subject.
Database keep context
2.
=============== userinfo ===============
sid can check by use sub.
GET https://openid.hydra:9002/oauth2/auth/sessions/consent?subject=foo@bar.com HTTP/1.1
https://github.com/ory/hydra-login-consent-node
When login success, context data be saved .
Can use
GET https://openid.hydra:9002/oauth2/auth/sessions/consent?subject=foo@bar.com HTTP/1.1
check by subject.
routes/login.js
hydra.acceptLoginRequest(challenge, {
context: {
"test1": "test1",
"test2": { "test2i": "test2i"}
},
Database keep context
Table name: hydra_oauth2_consent_request save context data. Here is Postgresql (pg).
===== Postgresql command ====
1. Login Postgresql (pg) docker2.
psql hydra -U hydra
#login pg (already in db cmd)
\dt;
select * from hydra_oauth2_consent_request;
=============== userinfo ===============
GET https://openid.hydra:9001/userinfo
Authorization: Bearer pFmYrUWtkGswx6RjvsGfgUAl4gV88id90P7hVLHUfQ4.AhbkWRawXV35S_V6Nq-Hf3DlBZ8Dl622sB4M3dg_hNQ
{
"sid": "891db392-859c-49d9-958c-83135f6986ee",
"sub": "foo@bar.com"
}
sid can check by use sub.
GET https://openid.hydra:9002/oauth2/auth/sessions/consent?subject=foo@bar.com HTTP/1.1
OpenID hydra docker-compose STOP
https://github.com/ory/examples/blob/master/full-stack/docker-compose.yml
Maybe use 5 min quickstart.yml better.
Maybe use 5 min quickstart.yml better.
OpenID hydra SSL problem Finish!
1、use docker-machine create vm get ip: 192.168.99.100
2、deploy
https://www.ory.sh/docs/next/hydra/configure-deploy
docker network create hydraguide
docker run \
--network hydraguide \
--name ory-hydra-example--postgres \
-e POSTGRES_USER=hydra \
-e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=hydra \
-d postgres:9.6
export SECRETS_SYSTEM=this_needs_to_be_the_same_always_and_also_very_$3cuR3-._
export DSN=postgres://hydra:secret@ory-hydra-example--postgres:5432/hydra?sslmode=disable
docker pull oryd/hydra:latest
docker run -it --rm \
--network hydraguide \
oryd/hydra:latest \
migrate sql --yes $DSN
=====creat ssl cert and key====
!!注意!! 產生方式改用 https://sueboy.blogspot.com/2019/08/openssl-self-signed-certificate.html 較為保險,不容易發生 ERR_SSL_VERSION_OR_CIPHER_MISMATCH 錯誤!
create two cert. 1. t.tt 2. openid.hydra
In vm
openssl genrsa -out t.tt.key 2048
openssl ecparam -genkey -name secp384r1 -out t.tt.key
openssl req -new -x509 -sha256 -key t.tt.key -out t.tt.crt -days 3650
Important!! t.tt.crt step: Common Name (e.g. server FQDN or YOUR name) []: t.tt
openssl genrsa -out openid.hydra.key 2048
openssl ecparam -genkey -name secp384r1 -out openid.hydra.key
openssl req -new -x509 -sha256 -key openid.hydra.key -out openid.hydra.crt -days 3650
Important!! openid.hydra.crt step: Common Name (e.g. server FQDN or YOUR name) []: openid.hydra
Use openid.hydra.key and openid.hydra.crt to base64 code
https://www.base64encode.org/
openid.hydra.key
-----BEGIN EC PARAMETERS-----BgUrgQQAIg==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MIGkAgEBBDCKnGgVqIW7YinbQeyPGyQ44Gu6UQDzU9HCKb33MifxRXE0dnu6+7Zu
0tBTqHPDuLygBwYFK4EEACKhZANiAARnx56OcxcrEdlbe8MtRuEqXev8DDrhzebF
386R8CdPX4eQb6fYzzAT/uwI0lL7oFiDXC7CBKZfTq7EK3xO3WZZRJ2k0D7NsKwg
TJYzrqOBis0MxkokaTYUrzhJ1pJcyfY=
-----END EC PRIVATE KEY-----
openid.hydra.crt
-----BEGIN CERTIFICATE-----MIICPTCCAcKgAwIBAgIJAMwF4bT4oJxtMAoGCCqGSM49BAMCMFwxCzAJBgNVBAYT
AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
aXRzIFB0eSBMdGQxFTATBgNVBAMMDG9wZW5pZC5oeWRyYTAeFw0xOTA2MTcwMTIx
MzdaFw0yOTA2MTQwMTIxMzdaMFwxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21l
LVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxFTATBgNV
BAMMDG9wZW5pZC5oeWRyYTB2MBAGByqGSM49AgEGBSuBBAAiA2IABGfHno5zFysR
2Vt7wy1G4Spd6/wMOuHN5sXfzpHwJ09fh5Bvp9jPMBP+7AjSUvugWINcLsIEpl9O
rsQrfE7dZllEnaTQPs2wrCBMljOuo4GKzQzGSiRpNhSvOEnWklzJ9qNQME4wHQYD
VR0OBBYEFG+vzfB1beg3UZtJXEvV9dMkXo6gMB8GA1UdIwQYMBaAFG+vzfB1beg3
UZtJXEvV9dMkXo6gMAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDaQAwZgIxALPv
86EHTTTIKpBGvT+ccV7wcH/8HR+slad/YPXKRVpwdCo52eTOWpCKgFjkG4BawQIx
ALlFdX0lI6g8WKyaE5f+2FdI1aejCAmwLOM6SDRa4UGn+Ckep8IcxmBL2/Be3IVz
8g==
-----END CERTIFICATE-----
SERVE_TLS_KEY_BASE64=LS0tLS1CRUdJTiBFQyBQQVJBTUVURVJTLS0tLS0KQmdVcmdRUUFJZz09Ci0tLS0tRU5EIEVDIFBBUkFNRVRFUlMtLS0tLQotLS0tLUJFR0lOIEVDIFBSSVZBVEUgS0VZLS0tLS0KTUlHa0FnRUJCRENLbkdnVnFJVzdZaW5iUWV5UEd5UTQ0R3U2VVFEelU5SENLYjMzTWlmeFJYRTBkbnU2KzdadQowdEJUcUhQRHVMeWdCd1lGSzRFRUFDS2haQU5pQUFSbng1Nk9jeGNyRWRsYmU4TXRSdUVxWGV2OEREcmh6ZWJGCjM4NlI4Q2RQWDRlUWI2Zll6ekFUL3V3STBsTDdvRmlEWEM3Q0JLWmZUcTdFSzN4TzNXWlpSSjJrMEQ3TnNLd2cKVEpZenJxT0JpczBNeGtva2FUWVVyemhKMXBKY3lmWT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=
SERVE_TLS_CERT_BASE64=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNQVENDQWNLZ0F3SUJBZ0lKQU13RjRiVDRvSnh0TUFvR0NDcUdTTTQ5QkFNQ01Gd3hDekFKQmdOVkJBWVQKQWtGVk1STXdFUVlEVlFRSURBcFRiMjFsTFZOMFlYUmxNU0V3SHdZRFZRUUtEQmhKYm5SbGNtNWxkQ0JYYVdSbgphWFJ6SUZCMGVTQk1kR1F4RlRBVEJnTlZCQU1NREc5d1pXNXBaQzVvZVdSeVlUQWVGdzB4T1RBMk1UY3dNVEl4Ck16ZGFGdzB5T1RBMk1UUXdNVEl4TXpkYU1Gd3hDekFKQmdOVkJBWVRBa0ZWTVJNd0VRWURWUVFJREFwVGIyMWwKTFZOMFlYUmxNU0V3SHdZRFZRUUtEQmhKYm5SbGNtNWxkQ0JYYVdSbmFYUnpJRkIwZVNCTWRHUXhGVEFUQmdOVgpCQU1NREc5d1pXNXBaQzVvZVdSeVlUQjJNQkFHQnlxR1NNNDlBZ0VHQlN1QkJBQWlBMklBQkdmSG5vNXpGeXNSCjJWdDd3eTFHNFNwZDYvd01PdUhONXNYZnpwSHdKMDlmaDVCdnA5alBNQlArN0FqU1V2dWdXSU5jTHNJRXBsOU8KcnNRcmZFN2RabGxFbmFUUVBzMndyQ0JNbGpPdW80R0t6UXpHU2lScE5oU3ZPRW5Xa2x6SjlxTlFNRTR3SFFZRApWUjBPQkJZRUZHK3Z6ZkIxYmVnM1VadEpYRXZWOWRNa1hvNmdNQjhHQTFVZEl3UVlNQmFBRkcrdnpmQjFiZWczClVadEpYRXZWOWRNa1hvNmdNQXdHQTFVZEV3UUZNQU1CQWY4d0NnWUlLb1pJemowRUF3SURhUUF3WmdJeEFMUHYKODZFSFRUVElLcEJHdlQrY2NWN3djSC84SFIrc2xhZC9ZUFhLUlZwd2RDbzUyZVRPV3BDS2dGamtHNEJhd1FJeApBTGxGZFgwbEk2ZzhXS3lhRTVmKzJGZEkxYWVqQ0Ftd0xPTTZTRFJhNFVHbitDa2VwOEljeG1CTDIvQmUzSVZ6CjhnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
docker run -d \
--name ory-hydra-example--hydra \
--network hydraguide \
-p 9001:4444 \
-p 9002:4445 \
-e SECRETS_SYSTEM=$SECRETS_SYSTEM \
-e DSN=$DSN \
-e URLS_SELF_ISSUER=https://openid.hydra:9001/ \
-e URLS_CONSENT=http://192.168.99.100:9020/consent \
-e URLS_LOGIN=http://192.168.99.100:9020/login \
-e LOG_LEVEL=debug \
-e OAUTH2_EXPOSE_INTERNAL_ERRORS=1 \
-e SERVE_PUBLIC_CORS_ENABLED=true \
-e SERVE_PUBLIC_CORS_ALLOWED_METHODS=POST,GET,PUT,DELETE \
-e SERVE_ADMIN_CORS_ENABLED=true \
-e SERVE_ADMIN_CORS_ALLOWED_METHODS=POST,GET,PUT,DELETE \
-e SERVE_TLS_KEY_BASE64=LS0tLS1CRUdJTiBFQyBQQVJBTUVURVJTLS0tLS0KQmdVcmdRUUFJZz09Ci0tLS0tRU5EIEVDIFBBUkFNRVRFUlMtLS0tLQotLS0tLUJFR0lOIEVDIFBSSVZBVEUgS0VZLS0tLS0KTUlHa0FnRUJCRENLbkdnVnFJVzdZaW5iUWV5UEd5UTQ0R3U2VVFEelU5SENLYjMzTWlmeFJYRTBkbnU2KzdadQowdEJUcUhQRHVMeWdCd1lGSzRFRUFDS2haQU5pQUFSbng1Nk9jeGNyRWRsYmU4TXRSdUVxWGV2OEREcmh6ZWJGCjM4NlI4Q2RQWDRlUWI2Zll6ekFUL3V3STBsTDdvRmlEWEM3Q0JLWmZUcTdFSzN4TzNXWlpSSjJrMEQ3TnNLd2cKVEpZenJxT0JpczBNeGtva2FUWVVyemhKMXBKY3lmWT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo= \
-e SERVE_TLS_CERT_BASE64=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNQVENDQWNLZ0F3SUJBZ0lKQU13RjRiVDRvSnh0TUFvR0NDcUdTTTQ5QkFNQ01Gd3hDekFKQmdOVkJBWVQKQWtGVk1STXdFUVlEVlFRSURBcFRiMjFsTFZOMFlYUmxNU0V3SHdZRFZRUUtEQmhKYm5SbGNtNWxkQ0JYYVdSbgphWFJ6SUZCMGVTQk1kR1F4RlRBVEJnTlZCQU1NREc5d1pXNXBaQzVvZVdSeVlUQWVGdzB4T1RBMk1UY3dNVEl4Ck16ZGFGdzB5T1RBMk1UUXdNVEl4TXpkYU1Gd3hDekFKQmdOVkJBWVRBa0ZWTVJNd0VRWURWUVFJREFwVGIyMWwKTFZOMFlYUmxNU0V3SHdZRFZRUUtEQmhKYm5SbGNtNWxkQ0JYYVdSbmFYUnpJRkIwZVNCTWRHUXhGVEFUQmdOVgpCQU1NREc5d1pXNXBaQzVvZVdSeVlUQjJNQkFHQnlxR1NNNDlBZ0VHQlN1QkJBQWlBMklBQkdmSG5vNXpGeXNSCjJWdDd3eTFHNFNwZDYvd01PdUhONXNYZnpwSHdKMDlmaDVCdnA5alBNQlArN0FqU1V2dWdXSU5jTHNJRXBsOU8KcnNRcmZFN2RabGxFbmFUUVBzMndyQ0JNbGpPdW80R0t6UXpHU2lScE5oU3ZPRW5Xa2x6SjlxTlFNRTR3SFFZRApWUjBPQkJZRUZHK3Z6ZkIxYmVnM1VadEpYRXZWOWRNa1hvNmdNQjhHQTFVZEl3UVlNQmFBRkcrdnpmQjFiZWczClVadEpYRXZWOWRNa1hvNmdNQXdHQTFVZEV3UUZNQU1CQWY4d0NnWUlLb1pJemowRUF3SURhUUF3WmdJeEFMUHYKODZFSFRUVElLcEJHdlQrY2NWN3djSC84SFIrc2xhZC9ZUFhLUlZwd2RDbzUyZVRPV3BDS2dGamtHNEJhd1FJeApBTGxGZFgwbEk2ZzhXS3lhRTVmKzJGZEkxYWVqQ0Ftd0xPTTZTRFJhNFVHbitDa2VwOEljeG1CTDIvQmUzSVZ6CjhnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= \
oryd/hydra:latest serve all
LOG_LEVEL ~ SERVE_ADMIN_CORS_ALLOWED_METHODS not important, add by yourself.
docker run -d \
--name ory-hydra-example--consent \
-p 9020:3000 \
--network hydraguide \
-e HYDRA_ADMIN_URL=https://ory-hydra-example--hydra:4445 \
-e NODE_TLS_REJECT_UNAUTHORIZED=0 \
oryd/hydra-login-consent-node:latest
docker run --rm -it \
-e HYDRA_ADMIN_URL=https://ory-hydra-example--hydra:4445 \
--network hydraguide \
oryd/hydra:latest \
clients create --skip-tls-verify \
--id auth-code-client \
--secret secret \
--grant-types authorization_code,refresh_token \
--response-types token,code,id_token \
--scope openid,offline,photos.read \
--callbacks https://t.tt:9010/callback
This step is different quickstart.yml. Use https and t.tt domain. quickstart.yml start serve --dangerous-force-httpAll become http. So last step can callback use http. This production way only use https. And token user only http. So use self OpenID client.
1. nano /etc/hosts or windows hosts
127.0.0.1 t.tt
192.168.99.100 openid.hydra
2. use golang OpenID client + ssl
https://blog.csdn.net/wangshubo1989/article/details/77980316https://github.com/denji/golang-tls
copy t.tt.key and t.tt.crt to go project
main.go
package main
import (
"context"
"crypto/tls"
"fmt"
"log"
"net/http"
"strings"
"golang.org/x/oauth2"
)
const htmlIndex = `
<html><body>
<a href="/HydraLogin">Log in with Hydra</a>
</body></html>
`
var endpotin = oauth2.Endpoint{
AuthURL: "https://openid.hydra:9001/oauth2/auth",
TokenURL: "https://openid.hydra:9001/oauth2/token",
}
var HydraOauthConfig = &oauth2.Config{
ClientID: "auth-code-client",
ClientSecret: "secret",
RedirectURL: "https://t.tt:9010/callback",
Scopes: []string{"openid", "offline", "photos.read"},
Endpoint: endpotin,
}
const oauthStateString = "gczxkznmjkrksgytsemvwgkf"
func main() {
http.HandleFunc("/", handleMain)
http.HandleFunc("/HydraLogin", handleHydraLogin)
http.HandleFunc("/callback", handleCallback)
//fmt.Println(http.ListenAndServe(":9010", nil))
err := http.ListenAndServeTLS(":9010", "t.tt.crt", "t.tt.key", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
func handleMain(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, htmlIndex)
}
func handleHydraLogin(w http.ResponseWriter, r *http.Request) {
url := HydraOauthConfig.AuthCodeURL(oauthStateString)
log.Println(url)
http.Redirect(w, r, url, http.StatusTemporaryRedirect)
}
func handleCallback(w http.ResponseWriter, r *http.Request) {
// add transport for self-signed certificate to context
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
sslcli := &http.Client{Transport: tr}
ctx := context.TODO()
ctx = context.WithValue(ctx, oauth2.HTTPClient, sslcli)
state := r.FormValue("state")
if state != oauthStateString {
log.Printf("invalid oauth state, expected '%s', got '%s'\n", oauthStateString, state)
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
return
}
log.Println("state:", state)
code := r.FormValue("code")
log.Println("code: ", code)
token, err := HydraOauthConfig.Exchange(ctx, code)
if err != nil {
log.Println("Code exchange failed with:", err)
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
return
}
TokenMsg := "<p>Token Info</p>"
TokenMsg += fmt.Sprintf("token.AccessToken : %s \n", token.AccessToken)
TokenMsg += fmt.Sprintf("token.TokenType : %s \n", token.TokenType)
TokenMsg += fmt.Sprintf("token.RefreshToken : %s \n", token.RefreshToken)
TokenMsg += fmt.Sprintf("token.Expiry : %s \n", token.Expiry)
TokenMsg += fmt.Sprintf("token Exra id_token : %s \n", token.Extra("id_token"))
TokenMsg += fmt.Sprintf("token Exra scope : %s \n", token.Extra("scope"))
log.Println(TokenMsg)
log.Println("===========all token==========")
log.Println("token: ", token)
log.Println("Authentication token.... ")
client := HydraOauthConfig.Client(ctx, token)
resp, err := client.Get("https://openid.hydra:9001/")
if err != nil {
log.Println(err)
} else {
log.Println("Authentication successful !!")
}
defer resp.Body.Close()
// show succes page
msg := "<p><strong>Success!</strong></p>"
msg += "<p>You are authenticated and can now return to the CLI.</p>"
msg += strings.ReplaceAll(TokenMsg, "\n", "<p>")
fmt.Fprintf(w, msg)
//response, err := http.Get("https://openid.hydra:9001/userinfo?access_token=" + token.AccessToken)
//defer response.Body.Close()
//contents, err := ioutil.ReadAll(response.Body)
//fmt.Fprintf(w, "Content: %s\n", contents)
}
Try https://t.tt Now can run finish all step.
hydra.rest
###
@audience = audience=
@max_age = max_age=0
@nonce = nonce=kwhqocyluutsstfouosxluqc
@prompt = prompt=
@response_type = response_type=code
@state = state=gczxkznmjkrksgytsemvwgkf
@client_id = client_id=auth-code-client
@scope = scope=openid+offline+photos.read
@redirect_url = redirect_url=https%3A%2F%2Ft.tt%3A9010%2Fcallback
@auth-tailpart = {{audience}}&{{max_age}}&{{nonce}}&{{prompt}}
@9001_auth = https://openid.hydra:9001/oauth2/auth?
### get hydra login page
Get {{9001_auth}}&{{client_id}}&{{redirect_url}}&{{scope}}&{{response_type}}&{{state}}&{{auth-tailpart}}
###
//提醒:csrf可以不更新,challenge一定要更新
@9020_login = http://192.168.99.100:9020/login
@9020_consent = http://192.168.99.100:9020/consent
@_csrf1 = Gxa6Hip4-J_A3L2kpRc72Iclw_Ql8eIcQiTc
@login_challenge = bc55b64985f1400b90a2c2741f8780f2
@email = foo@bar.com
@password = foobar
### get login
GET https://192.168.99.100:9002/oauth2/auth/requests/login?login_challenge={{login_challenge}}
### login
#POST {{9020_login}}
#Content-Type: application/x-www-form-urlencoded
#_csrf={{_csrf1}}
#&challenge={{login_challenge}}
#&email={{email}}
#&password={{password}}
### accept login
PUT https://192.168.99.100:9002/oauth2/auth/requests/login/accept?login_challenge={{login_challenge}}
Content-Type: application/json
{
"subject": "foo@bar.com",
"remember": false,
"remember_for": 3600
}
@login_verifier = login_verifier=1025ccb8109047668715c8162459d6de
### get conent
GET {{9001_auth}}{{login_verifier}}&{{client_id}}&{{redirect_url}}&{{scope}}&{{response_type}}&{{state}}&{{auth-tailpart}}
###
@consent_challenge = d23b6822d88842078a0d83677e8709a8
@_csrf2 = PLSPrz8R-GqmzKwgMtNus3LiX-p9Oh0QaLnQ
### requests consent
###GET {{9020_consent}}?consent_challenge={{consent_challenge}}
### get conent scope
GET https://192.168.99.100:9002/oauth2/auth/requests/consent?consent_challenge={{consent_challenge}}
@submit = Allow access
### accept conent scope
PUT https://192.168.99.100:9002/oauth2/auth/requests/consent/accept?consent_challenge={{consent_challenge}}
Content-Type: application/json
{
"grant_scope": ["openid", "photos.read"],
"session": {
"access_token": { "foo": "bar" },
"id_token": { "baz": "bar" }
}
}
@consent_verifier = consent_verifier=ed04b20447c343338e9000b2db640f3c
### get auth token
GET {{9001_auth}}{{consent_verifier}}&{{client_id}}&{{redirect_url}}&{{scope}}&{{response_type}}&{{state}}&{{auth-tailpart}}
### http://192.168.99.100:4444/oauth2/auth?audience=&client_id=auth-code-client&consent_verifier=a643ae2e056543fabbd8d6f747e8a30c&max_age=0&nonce=chscixgzceuosfcocvvmjngj&prompt=&redirect_uri=http%3A%2F%2F127.0.0.1%3A5555%2Fcallback&response_type=code&scope=openid+offline&state=oplovvughuyzixqdvxnortrq
@token= xLPcJ3tobDqGUDxIVTxWt2p7w_odZSV22IAlUf5QPZU.YD6R_xKQ2ldCLbEV7mmc01E6ZLzemzdEC5H4-otTMPg
### userinfo
GET https://openid.hydra:9001/userinfo
Authorization: Bearer {{token}}
### introspect
POST https://openid.hydra:9002/oauth2/introspect
Content-Type: application/x-www-form-urlencoded
token={{token}}
&scope=openid+photos.read
###
GET https://openid.hydra:9002/oauth2/auth/sessions/consent?subject=foo@bar.com HTTP/1.1
PS:&scope=openid+photos.read can remove.
PS:
Here REST Client still return login page. go main server error log:
Post https://openid.hydra:9001/oauth2/token: x509: certificate signed by unknown authority
This is Go Server problem. See main.go Line:55-61 82-94 Fix this problem.
========== old ==========
3、Now have problem is token user. When you run *A, try to open web broswer. http://192.168.99.100:9010 then click "Authorize application" get error.
Because "Authorize application" still is 127.0.0.1. No way to change. So copy Link change it.
https://192.168.99.100:9001/oauth2/auth?audience=&client_id=auth-code-client&max_age=0&nonce=ylnybhabgcjllcxbfvhfjdfe&prompt=&redirect_uri=http%3A%2F%2F192.168.99.100%3A9010%2Fcallback&response_type=code&scope=openid+offline+photos.read&state=shqjytubxbrzqwtiskwwpfdp
Copy fix link to go. Fllow website.
4、The Big problem is Allow access only get error. Can't know why.
Rest Client || visual studio code
Even by step to run. Still get error......OpenID grant_type
https://blog.yorkxin.org/2013/09/30/oauth2-3-endpoints.html
Grant Type
Grant Type 透過 grant_type 參數來指定,其值定義如下:
值 意義
authorization_code 用 Authorization Code 求 Access Token (Authorization Code Grant Flow)。
password 用 Resorce Owner Password Credentials 求 Access Token (Resource Owner Password Credentials Grant Flow)。
client_credentials 用 Client Credentials 求 Access Token (Client Credentials Grant Flow)。
refresh_token 用 Refresh Token 換發 Access Token。
Grant Type
Grant Type 透過 grant_type 參數來指定,其值定義如下:
值 意義
authorization_code 用 Authorization Code 求 Access Token (Authorization Code Grant Flow)。
password 用 Resorce Owner Password Credentials 求 Access Token (Resource Owner Password Credentials Grant Flow)。
client_credentials 用 Client Credentials 求 Access Token (Client Credentials Grant Flow)。
refresh_token 用 Refresh Token 換發 Access Token。
OpenID hydra dex
F... Now follow step run, Get level=error msg="An error occurred" debug="No CSRF value available in the session cookie" description="The request is not allowed" error=request_forbidden hint="You are not allowed to perform this action."
If you run same broswer and restart docker or clear cookie, do many way. Just try broswer private mode.
Try dex docker or binary failed, it's be pass.
Hydra docker-compose
1、get https://github.com/ory/hydra
docker-compose -f quickstart.yml -f quickstart-postgres.yml up --build
注意 quickstart.yml
run docker on host or run binary on host. hydra 5 minutes demo "IP Used" is 127.0.0.1
version: '3'
services:
hydra:
image: oryd/hydra:latest
ports:
- "4444:4444" # Public port
- "4445:4445" # Admin port
- "5555:5555" # Port for hydra token user
command:
serve all --dangerous-force-http
environment:
- URLS_SELF_ISSUER=http://127.0.0.1:4444
- URLS_CONSENT=http://127.0.0.1:3000/consent
- URLS_LOGIN=http://127.0.0.1:3000/login
- URLS_LOGOUT=http://127.0.0.1:3000/logout
- DSN=memory
- SECRETS_SYSTEM=youReallyNeedToChangeThis
- OIDC_SUBJECT_TYPES_SUPPORTED=public,pairwise
- OIDC_SUBJECT_TYPE_PAIRWISE_SALT=youReallyNeedToChangeThis
restart: unless-stopped
consent:
environment:
- HYDRA_ADMIN_URL=http://hydra:4445
image: oryd/hydra-login-consent-node:latest
ports:
- "3000:3000"
restart: unless-stopped
run VM or real server is real ip. Ex: 192.168.99.100 (docker-machine)
version: '3'
services:
hydra:
image: oryd/hydra:latest
ports:
- "4444:4444" # Public port
- "4445:4445" # Admin port
- "5555:5555" # Port for hydra token user
command:
serve all --dangerous-force-http
environment:
- URLS_SELF_ISSUER=http://192.168.99.100:4444
- URLS_CONSENT=http://192.168.99.100:3000/consent
- URLS_LOGIN=http://192.168.99.100:3000/login
- URLS_LOGOUT=http://192.168.99.100:3000/logout
- DSN=memory
- SECRETS_SYSTEM=youReallyNeedToChangeThis
- OIDC_SUBJECT_TYPES_SUPPORTED=public,pairwise
- OIDC_SUBJECT_TYPE_PAIRWISE_SALT=youReallyNeedToChangeThis
restart: unless-stopped
consent:
environment:
- HYDRA_ADMIN_URL=http://hydra:4445
image: oryd/hydra-login-consent-node:latest
ports:
- "3000:3000"
restart: unless-stopped
If have cors problems. see https://github.com/ory/hydra/blob/master/quickstart-cors.yml
Check hydra OpenID startup or not 確認是否正常啟動
http://192.168.99.100:4444/.well-known/jwks.json
Create clients
Download hydra binary.
https://www.ory.sh/docs/next/hydra/install#download-binarieshttps://github.com/ory/hydra/releases
https://github.com/ory/hydra/releases/tag/v1.0.0-rc.15
PS: Maybe version renew, so try to get best new.
hydra clients create --endpoint http://192.168.99.100:4445/ --id auth-code-client --secret secret --grant-types authorization_code,refresh_token --response-types code,id_token --scope openid,offline --callbacks http://127.0.0.1:5555/callback
! new version use endpoint, different before auth-url and token-url, But I think you still can use old way... Maybe
! scope "openid,offline" next step must use same. So scope is definend by yourself.
Thanks https://dotblogs.com.tw/liguobao/2018/12/30/132746
Check clients 查看clients
hydra clients list --endpoint http://192.168.99.100:4445
Emu all step OpenID
Fllow website that run command pop website. If no pop, http://127.0.0.1:5555/
hydra token user --client-id auth-code-client --client-secret secret --endpoint http://192.168.99.100:4444 --port 5555 --scope openid,offline
This step will run server on port 5555
! here scope "openid,offline" must same before create.
Get userinfo. Copy Access Token replace string after Bearer
curl -X GET http://192.168.99.100:4444/userinfo -H 'Accept: application/json' -H 'Authorization: Bearer MmadDHs3VdWC7LZTIdBKUHyzgsWHe2XbzHpwjKrF7Rs.tXlg7rShEEbkcczNWJGS84sIvokTF6Ae7bhSQZfHMgA'
Get json
{"sid":"c7d5665b-76e7-475a-95a8-cc521352663b","sub":"foo@bar.com"}
Modify edit add userinfo info.
https://github.com/ory/hydra-login-consent-node/blob/master/routes/login.js
subject: 'foo@bar.com', -> subject: 'foo@bar.com-success',
This docker test
1. docker ps
2. get oryd/hydra-login-consent-node:v1.0.0-rc.10 containerid
3. docker exec -it containerid /bin/sh
4. vi bin/www change port 3000 - > 3001
5. vi routes/login.js subject: 'foo@bar.com', => subject: 'foo@bar.com--success',
5. node ./bin/www &
6. ps
7. kill old node (be exit container)
8. docker exec -it containerid /bin/sh
9. vi bin/www change port 3001 - > 3000
10. node ./bin/www &
11. kill old node (be exit container)
12. docker exec -it containerid /bin/sh
13. netstat -nlp (check port 3000)
====================
https://mileschou.github.io/auth-notes/src/hydra/user-login-and-consent-flow.html#oauth-2-0-%E8%88%87-open-id-connect
====================
https://dotblogs.com.tw/liguobao/2018/12/30/132746
OAUTH2_ISSUER_URL hydra所在的地址
OAUTH2_CONSENT_URL 授权页面地址
OAUTH2_LOGIN_URL 登录页面地址
XX应用请求授权
-> 跳转到OAUTH2_LOGIN_URL地址
-> 登录成功
->跳转到OAUTH2_CONSENT_URL授权页面
-> 授权成功
->回调XX应用地址并且返回相关授权code/token
-> XX应用使用code/token获取用户信息或者其他操作
[轉]鋪柏油路
我是退休的營造工程師,我自己也開營造廠。 做營造的人不會穿皮鞋,就算工程師>工地主任>工程部經理,真的在做營造工程的只會穿運動鞋/安全鞋,很少機會去穿西裝皮鞋,說不好聽的你去看上酒店喝酒的一線營造業還是只穿運動鞋(當年真是天天花天酒地除了星期日)。
台灣的工程常常都是做完賺經驗,就是前面的設計仿歐美失敗,然後失敗中學經驗再修改,政府很多土木工程都是從設計就不是完美,大部分馬路自今還是設計缺陷,沒有因台灣環境去真的更改,還是沿用古老的傳統。
營造業基本上有在標政府工程的大概都知道工程的黑幕,高雄從謝長廷開始就是大黑特黑,不是陳菊。重點是不是他們的人你有錢還標不了工程。
懂理論與實際工程經驗不一樣,確實 料 一直是營造工程最真實的問題,不是一天兩天是3X年前我第一次進工地就知道的問題,另外 3cm的柏油做不起來很快會龜裂不耐用,最低都是5cm沒有3cm的。
柏油路 最重要的除了是原料之外還有路基,下面的給配有無確實的夯實才是耐用王道,因為載力是往下傳;破壞力是往前延伸。
一般馬路與高速公路的使用方式不同,高速公路是高速行駛在上面說最庶民語言就是飛過去,馬路是碾壓在上面,因為各種車子的起步與慢速最傷馬路,所以設計要不同。
香港的馬路有雙層巴士,這是數量最多的大型車輛,當然其他連結車 貨車都有。但是單論台灣 香港一般馬路最多的大型車就是公車,兩地的馬路除了工程破壞從鋪不論之外,香港的馬路真的就是比台灣好比台灣耐用,我看1X年了到今年2019年5月還再看有公車行駛的山坡地他們怎麼鋪馬路,說真的台灣做不到。
香港的馬路基本配置法(大部分的馬路皆一樣),基本有三層,原始層(這部分做得很確實夯實)/路基(標準30cm)/柏油(30cm),只要看到他們挖馬路的時候,挖起來的柏油就是30cm,大部分的馬路。有部分馬路統一不用柏油例如公車站,這就要用剛性路面(硬),就是台灣收費站的區域你不會看到柏油的原因<<<<這才是重點 重點 重點。
香港我有住的地方是一般街市(公屋/菜市場),我附近的馬路我知道的就已經10年沒重新鋪過,路還是一樣的平,只是退色會變灰白色。
李四川副市長是真的懂工程的人,以前他在台北市的時候,我剛好在做北市X期汙水工程的工地主任。
您好、我做過柏油工程及自來水管工程及當過水泥預拌混凝土司機,這3個工作共10幾年。 我對柏油路有一些看法。 您影片中只是一小部分原因,還有更多原因,那我簡單分享一下,讓大眾了解為何柏油路面無法鋪好。 1: 柏油路面下有很多工程。如自來水、電信、寬頻、瓦斯、第四台等管線,在做這些工程時會挖開柏油路面,把這些管線埋在地底1米-1米多不等,重點在於「回填」,地底的紮實度,直接影響路面狀況。 2: 依工程規定必須叫水泥預拌車用(clsm水泥回填),地底才會紮實,大車開過才不會塌陷,及水泥不會被雨水滲透流失。 可以試想一下,下面土是軟的、上面是柏油(就算上面鋪再厚),地底還是軟的,大車開過或下大雨後,導致柏油路面坍塌或地底被雨水掏空後直接柏油路面破洞。 很多工程都未依規定,直接「原土」回填,為了省「水泥」的錢,相當可觀唷。 或原土回填後上面鋪薄薄的水泥拍照📷,來騙公家機關(其實官官相護就是收回扣)。 或用品質很差的clsm(水泥)來回填,跟如您影片中很差的柏油品質一樣。
台灣的工程常常都是做完賺經驗,就是前面的設計仿歐美失敗,然後失敗中學經驗再修改,政府很多土木工程都是從設計就不是完美,大部分馬路自今還是設計缺陷,沒有因台灣環境去真的更改,還是沿用古老的傳統。
營造業基本上有在標政府工程的大概都知道工程的黑幕,高雄從謝長廷開始就是大黑特黑,不是陳菊。重點是不是他們的人你有錢還標不了工程。
懂理論與實際工程經驗不一樣,確實 料 一直是營造工程最真實的問題,不是一天兩天是3X年前我第一次進工地就知道的問題,另外 3cm的柏油做不起來很快會龜裂不耐用,最低都是5cm沒有3cm的。
柏油路 最重要的除了是原料之外還有路基,下面的給配有無確實的夯實才是耐用王道,因為載力是往下傳;破壞力是往前延伸。
一般馬路與高速公路的使用方式不同,高速公路是高速行駛在上面說最庶民語言就是飛過去,馬路是碾壓在上面,因為各種車子的起步與慢速最傷馬路,所以設計要不同。
香港的馬路有雙層巴士,這是數量最多的大型車輛,當然其他連結車 貨車都有。但是單論台灣 香港一般馬路最多的大型車就是公車,兩地的馬路除了工程破壞從鋪不論之外,香港的馬路真的就是比台灣好比台灣耐用,我看1X年了到今年2019年5月還再看有公車行駛的山坡地他們怎麼鋪馬路,說真的台灣做不到。
香港的馬路基本配置法(大部分的馬路皆一樣),基本有三層,原始層(這部分做得很確實夯實)/路基(標準30cm)/柏油(30cm),只要看到他們挖馬路的時候,挖起來的柏油就是30cm,大部分的馬路。有部分馬路統一不用柏油例如公車站,這就要用剛性路面(硬),就是台灣收費站的區域你不會看到柏油的原因<<<<這才是重點 重點 重點。
香港我有住的地方是一般街市(公屋/菜市場),我附近的馬路我知道的就已經10年沒重新鋪過,路還是一樣的平,只是退色會變灰白色。
李四川副市長是真的懂工程的人,以前他在台北市的時候,我剛好在做北市X期汙水工程的工地主任。
您好、我做過柏油工程及自來水管工程及當過水泥預拌混凝土司機,這3個工作共10幾年。 我對柏油路有一些看法。 您影片中只是一小部分原因,還有更多原因,那我簡單分享一下,讓大眾了解為何柏油路面無法鋪好。 1: 柏油路面下有很多工程。如自來水、電信、寬頻、瓦斯、第四台等管線,在做這些工程時會挖開柏油路面,把這些管線埋在地底1米-1米多不等,重點在於「回填」,地底的紮實度,直接影響路面狀況。 2: 依工程規定必須叫水泥預拌車用(clsm水泥回填),地底才會紮實,大車開過才不會塌陷,及水泥不會被雨水滲透流失。 可以試想一下,下面土是軟的、上面是柏油(就算上面鋪再厚),地底還是軟的,大車開過或下大雨後,導致柏油路面坍塌或地底被雨水掏空後直接柏油路面破洞。 很多工程都未依規定,直接「原土」回填,為了省「水泥」的錢,相當可觀唷。 或原土回填後上面鋪薄薄的水泥拍照📷,來騙公家機關(其實官官相護就是收回扣)。 或用品質很差的clsm(水泥)來回填,跟如您影片中很差的柏油品質一樣。
ethereum smart contract 基本
uint256 => 2^256
byte32 => 2^8^32 (byte=2^8) or 32個byte 放32字元(ascii)
0x => HEX 16進位
0x64 => 6 * (16^1) + 4 * (16^0) = 100
0x0164 => 1 * (16^2) + 6 * (16^1) + 4 * (16^0) = 365
0x HEX 16進位 最小0 最大F
回到最上面byte32 轉成 0x HEX 為了避免太長,2^8 = 256 => 16^2 => 16位元顯示要兩位 0~256 => 00~FF || FF => 15 * (16^1) + 15 * (16^0)
所以 0x0164,通常都是兩位處理 0x 01 64
unit256 = byte32
000000000000000000000000000000000000000000000000006a94d74f430000
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2
Hex number: 6a94d74f430000
Decimal number: 30000000000000000
Binary number: 1101010100101001101011101001111010000110000000000000000
Binary number: 110 1010 1001 0100 1101 0111 0100 1111 0100 0011 0000 0000 0000 0000
Decimal calculation:
0 = (0 × 16⁶³) + (0 × 16⁶²) + (0 × 16⁶¹) + (0 × 16⁶⁰) + (0 × 16⁵⁹) + (0 × 16⁵⁸) + (0 × 16⁵⁷) + (0 × 16⁵⁶) + (0 × 16⁵⁵) + (0 × 16⁵⁴) + (0 × 16⁵³) + (0 × 16⁵²) + (0 × 16⁵¹) + (0 × 16⁵⁰) + (0 × 16⁴⁹) + (0 × 16⁴⁸) + (0 × 16⁴⁷) + (0 × 16⁴⁶) + (0 × 16⁴⁵) + (0 × 16⁴⁴) + (0 × 16⁴³) + (0 × 16⁴²) + (0 × 16⁴¹) + (0 × 16⁴⁰) + (0 × 16³⁹) + (0 × 16³⁸) + (0 × 16³⁷) + (0 × 16³⁶) + (0 × 16³⁵) + (0 × 16³⁴) + (0 × 16³³) + (0 × 16³²) + (0 × 16³¹) + (0 × 16³⁰) + (0 × 16²⁹) + (0 × 16²⁸) + (0 × 16²⁷) + (0 × 16²⁶) + (0 × 16²⁵) + (0 × 16²⁴) + (0 × 16²³) + (0 × 16²²) + (0 × 16²¹) + (0 × 16²⁰) + (0 × 16¹⁹) + (0 × 16¹⁸) + (0 × 16¹⁷) + (0 × 16¹⁶) + (0 × 16¹⁵) + (0 × 16¹⁴) + (6 × 16¹³) + (10 × 16¹²) + (9 × 16¹¹) + (4 × 16¹⁰) + (13 × 16⁹) + (7 × 16⁸) + (4 × 16⁷) + (15 × 16⁶) + (4 × 16⁵) + (3 × 16⁴) + (0 × 16³) + (0 × 16²) + (0 × 16¹) + (0 × 16⁰) = 30000000000000000
=====
address last 20 bytes Byte20 換成 Hex 就40位元(characters)加上0x,就有42 characters
EX: cd2a3d9f938e13cd947ec05abc7fe734df8dd826
[轉][Solidity] 壓縮智能合約的輸入資料
https://medium.com/joyso/solidity-%E5%A3%93%E7%B8%AE%E6%99%BA%E8%83%BD%E5%90%88%E7%B4%84%E7%9A%84%E8%BC%B8%E5%85%A5%E8%B3%87%E6%96%99-65a870d1f04e
ethereum smart contract private value not safe
https://hackernoon.com/your-private-solidity-variable-is-not-private-save-it-before-it-becomes-public-52a723f29f5e
上面範例中,play(100)被呼叫後,從transcation data內得知
0x6587f6ec0000000000000000000000000000000000000000000000000000000000000064
然後先取得play()這部份的data
bytes4(keccak256('play(uint)'))
然後得知 0000000000000000000000000000000000000000000000000000000000000064 就是 uint部份,得到的這個值是經過hex才顯示的
byte32:00 為1個byte(16 bits),共32個
64=> 6 * (16^1) + 4 * (16^0) = 100
uint256 => 2^256 => 8^32 => byte32
上面範例中,play(100)被呼叫後,從transcation data內得知
0x6587f6ec0000000000000000000000000000000000000000000000000000000000000064
然後先取得play()這部份的data
bytes4(keccak256('play(uint)'))
然後得知 0000000000000000000000000000000000000000000000000000000000000064 就是 uint部份,得到的這個值是經過hex才顯示的
byte32:00 為1個byte(16 bits),共32個
64=> 6 * (16^1) + 4 * (16^0) = 100
uint256 => 2^256 => 8^32 => byte32
ubuntu 18 sudo 卡頓
https://ywnz.com/linuxjc/2024.html
在Ubuntu Server 18.04 LTS下遇到了sudo速度非常慢的问题,具体表现是在提交命令之后大概需要10秒左右才有输入sudo密码或者开始运行,su命令同样也非常慢。这在升级前使用Ubuntu Server 16.04 LTS并没有,显然可能是Ubuntu Server 18.04 LTS版本的问题。
问题的原因
Ubuntu Server被设计成一种类似于分布式的操作系统网结构,允许/etc/sudoers中的成员不在本机上。从而sudo时会先从网络上寻找可能的sudoer然后才是本地,而这10s左右的时间就是整个DNS流程的最长时间。
解决办法
首先输入hostname,得到本机当前的互联网名称(大概跟windows下的计算机名称差不多)。然后使用su或sudo打开/etc/hosts,添加一行:
127.0.0.1计算机名计算机名.localdomain
关闭并保存。这样处理后sudo速度恢复正常。
在Ubuntu Server 18.04 LTS下遇到了sudo速度非常慢的问题,具体表现是在提交命令之后大概需要10秒左右才有输入sudo密码或者开始运行,su命令同样也非常慢。这在升级前使用Ubuntu Server 16.04 LTS并没有,显然可能是Ubuntu Server 18.04 LTS版本的问题。
问题的原因
Ubuntu Server被设计成一种类似于分布式的操作系统网结构,允许/etc/sudoers中的成员不在本机上。从而sudo时会先从网络上寻找可能的sudoer然后才是本地,而这10s左右的时间就是整个DNS流程的最长时间。
解决办法
首先输入hostname,得到本机当前的互联网名称(大概跟windows下的计算机名称差不多)。然后使用su或sudo打开/etc/hosts,添加一行:
127.0.0.1
关闭并保存。这样处理后sudo速度恢复正常。
訂閱:
文章 (Atom)




