docker-compose

  
version: '3.3'  
  
services:  
  ory-hydra-postgres:  
    image: postgres:9.6  
    #restart: always  
    environment:  
      - POSTGRES_USER=hydra  
      - POSTGRES_PASSWORD=secret  
      - POSTGRES_DB=hydra  
    volumes:  
      - hydradata:/var/lib/postgresql/data:rw  
    networks:  
      - openid  
  # 第一次執行postgres要做資料庫格式建立 PS: network依佈屬環境為主 docker network ls 確認  
  # docker run -it --rm \  
  #   --network openid \  
  #   oryd/hydra:latest \  
  #   migrate sql --yes postgres://hydra:secret@ory-hydra-postgres:5432/hydra?sslmode=disable  
    
  ory-hydra:  
    image: oryd/hydra:latest  
    restart: unless-stopped  
    ports:  
      - "9001:4444"  
      - "9002:4445"  
    environment:  
      - SECRETS_SYSTEM=this_needs_to_be_the_same_a  
      - DSN=postgres://hydra:secret@ory-hydra-postgres:5432/hydra?sslmode=disable  
      - URLS_SELF_ISSUER=https://openid.hydra:9001/  
      - URLS_CONSENT=http://192.168.99.100:9020/consent  
      - URLS_LOGIN=http://192.168.99.100:9020/login  
      - LOG_LEVEL=debug  
      - OAUTH2_EXPOSE_INTERNAL_ERRORS=true  
      - SERVE_PUBLIC_CORS_ENABLED=true  
      - SERVE_PUBLIC_CORS_ALLOWED_METHODS=POST,GET,PUT,DELETE  
      - SERVE_ADMIN_CORS_ENABLED=true  
      - SERVE_ADMIN_CORS_ALLOWED_METHODS=POST,GET,PUT,DELETE  
      - SERVE_TLS_KEY_BASE64=LS0tLS1CRUdJTiBFQyBQQVJBTUVURVJTLS0tLS0KQmdVcmdRUUFJZz09Ci0tLS0tRU5EIEVDIFBBUkFNRVRFUlMtLS0tLQotLS0tLUJFR0lOIEVDIFBSSVZBVEUgS0VZLS0tLS0KTUlHa0FnRUJCRENLbkdnVnFJVzdZaW5iUWV5UEd5UTQ0R3U2VVFEelU5SENLYjMzTWlmeFJYRTBkbnU2KzdadQowdEJUcUhQRHVMeWdCd1lGSzRFRUFDS2haQU5pQUFSbng1Nk9jeGNyRWRsYmU4TXRSdUVxWGV2OEREcmh6ZWJGCjM4NlI4Q2RQWDRlUWI2Zll6ekFUL3V3STBsTDdvRmlEWEM3Q0JLWmZUcTdFSzN4TzNXWlpSSjJrMEQ3TnNLd2cKVEpZenJxT0JpczBNeGtva2FUWVVyemhKMXBKY3lmWT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=  
      - SERVE_TLS_CERT_BASE64=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNQVENDQWNLZ0F3SUJBZ0lKQU13RjRiVDRvSnh0TUFvR0NDcUdTTTQ5QkFNQ01Gd3hDekFKQmdOVkJBWVQKQWtGVk1STXdFUVlEVlFRSURBcFRiMjFsTFZOMFlYUmxNU0V3SHdZRFZRUUtEQmhKYm5SbGNtNWxkQ0JYYVdSbgphWFJ6SUZCMGVTQk1kR1F4RlRBVEJnTlZCQU1NREc5d1pXNXBaQzVvZVdSeVlUQWVGdzB4T1RBMk1UY3dNVEl4Ck16ZGFGdzB5T1RBMk1UUXdNVEl4TXpkYU1Gd3hDekFKQmdOVkJBWVRBa0ZWTVJNd0VRWURWUVFJREFwVGIyMWwKTFZOMFlYUmxNU0V3SHdZRFZRUUtEQmhKYm5SbGNtNWxkQ0JYYVdSbmFYUnpJRkIwZVNCTWRHUXhGVEFUQmdOVgpCQU1NREc5d1pXNXBaQzVvZVdSeVlUQjJNQkFHQnlxR1NNNDlBZ0VHQlN1QkJBQWlBMklBQkdmSG5vNXpGeXNSCjJWdDd3eTFHNFNwZDYvd01PdUhONXNYZnpwSHdKMDlmaDVCdnA5alBNQlArN0FqU1V2dWdXSU5jTHNJRXBsOU8KcnNRcmZFN2RabGxFbmFUUVBzMndyQ0JNbGpPdW80R0t6UXpHU2lScE5oU3ZPRW5Xa2x6SjlxTlFNRTR3SFFZRApWUjBPQkJZRUZHK3Z6ZkIxYmVnM1VadEpYRXZWOWRNa1hvNmdNQjhHQTFVZEl3UVlNQmFBRkcrdnpmQjFiZWczClVadEpYRXZWOWRNa1hvNmdNQXdHQTFVZEV3UUZNQU1CQWY4d0NnWUlLb1pJemowRUF3SURhUUF3WmdJeEFMUHYKODZFSFRUVElLcEJHdlQrY2NWN3djSC84SFIrc2xhZC9ZUFhLUlZwd2RDbzUyZVRPV3BDS2dGamtHNEJhd1FJeApBTGxGZFgwbEk2ZzhXS3lhRTVmKzJGZEkxYWVqQ0Ftd0xPTTZTRFJhNFVHbitDa2VwOEljeG1CTDIvQmUzSVZ6CjhnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=  
    networks:  
      - openid  
  
  
# 快速建立 auth-doce-client PS: network依佈屬環境為主 docker network ls 確認  
#docker run --rm -it \  
#  -e HYDRA_ADMIN_URL=https://ory-hydra:4445 \  
#  --network openid \  
#  oryd/hydra:latest \  
#  clients create --skip-tls-verify \  
#    --id auth-code-client \  
#    --secret secret \  
#    --grant-types authorization_code,refresh_token \  
#    --response-types code,id_token,token \  
#    --scope openid,offline,photos.read \  
#    --callbacks https://t.tt:9010/callback  
  
  ory-hydra-login-consent:  
    #image: oryd/hydra-login-consent-node:latest  
    build:  
      context: hydra-login-consent-node/  
    restart: unless-stopped  
    ports:  
      - "9020:3000"  
    environment:  
      - HYDRA_ADMIN_URL=https://ory-hydra:4445  
      - NODE_TLS_REJECT_UNAUTHORIZED=0  
    volumes:  
      - hydraloginconsent:/usr/src/app:rw  
    depends_on:  
      - mariadb  
    networks:  
      - openid  
    
  mariadb:  
    image: mariadb:10.4.6  
    #restart: always  
    environment:  
      - MYSQL_ROOT_PASSWORD=secret  
      - MYSQL_DATABASE=openid  
    command: ['--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci']  
    #第一次使執行db_init_sql.txt  
    networks:  
      - openid  
  
  adminer:  
    image: adminer  
    restart: always  
    ports:  
      - 8080:8080  
    depends_on:  
      - mariadb  
    networks:  
      - openid  
  
volumes:    
  hydradata:   
  hydraloginconsent:  
      
networks:  
  openid:  
    driver: bridge  
  

Use adminer test maraidb: http://192.168.99.100:8080 root/secret

mariadb init

  
DROP DATABASE IF EXISTS `openid`;  
CREATE DATABASE `openid` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */;  
USE `openid`;  
  
DROP TABLE IF EXISTS `user`;  
CREATE TABLE `user` (  
  `id` int(11) NOT NULL AUTO_INCREMENT,  
  `name` text COLLATE utf8mb4_unicode_ci NOT NULL,  
  `email` text COLLATE utf8mb4_unicode_ci NOT NULL,  
  `password` text COLLATE utf8mb4_unicode_ci NOT NULL,  
  PRIMARY KEY (`id`)  
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;  
  
INSERT INTO `user` (`id`, `name`, `email`, `password`) VALUES  
(1, 'foobar', 'foo@bar.com', '3858f62230ac3c915f300c664312c63f');  

  
"md5": "^2.2.1",  
"mysql": "^2.17.1"  

  
var mysql = require('mysql');  
  
var pool = mysql.createPool({  
  host     : 'mariadb',  
  user     : 'root',  
  password : 'secret',  
  database: 'openid'  
});  
  
var query=function(sql,options,callback){    
  pool.getConnection(function(err,conn){    
    pool.query  
    if(err){    
      callback(err,null,null);    
    }else{    
      conn.query(sql,options,function(err,results,fields){    
        //释放连接    
        conn.release();    
        //事件驱动回调    
        callback(err,results,fields);    
      });    
    }    
  });    
};   
  
module.exports = {query, pool}  

  
...  
  
router.post('/', csrfProtection, function (req, res, next) {  
  // The challenge is now a hidden input field, so let's take it from the request body instead  
  var challenge = req.body.challenge;  
  
  var sql = "select count(*) as count from user where email = ? and password = ?"  
  var params = [req.body.email, md5(req.body.password)]  
  //db.get(sql, params, (err, row) => {  
  pool.query(sql, params, (err, row) => {  
    if (err) {  
      res.status(400).json({"db error":err.message});  
      return;  
    }  
  
    if(!(row.count==1)){ //找不到  
      res.render('login', {  
        csrfToken: req.csrfToken(),  
    
        challenge: challenge,  
    
        error: 'The username / password combination is not correct'  
      });  
      return;  
    }  
  
    hydra.acceptLoginRequest(challenge, {  
      // Subject is an alias for user ID. A subject can be a random string, a UUID, an email address, ....  
      subject: req.body.email,  
    
      // This tells hydra to remember the browser and automatically authenticate the user in future requests. This will  
      // set the "skip" parameter in the other route to true on subsequent requests!  
      remember: Boolean(req.body.remember),  
    
      // When the session expires, in seconds. Set this to 0 so it will never expire.  
      remember_for: 3600,  
    
      // Sets which "level" (e.g. 2-factor authentication) of authentication the user has. The value is really arbitrary  
      // and optional. In the context of OpenID Connect, a value of 0 indicates the lowest authorization level.  
      // acr: '0',  
    })  
    .then(function (response) {  
      // All we need to do now is to redirect the user back to hydra!  
      res.redirect(response.redirect_to);  
    })  
    // This will handle any error that happens when making HTTP calls to hydra  
    .catch(function (error) {  
      next(error);  
    });  
  
  });  
  
  // Let's check if the user provided valid credentials. Of course, you'd use a database or some third-party service  
  // for this!  
  // if (!(req.body.email === 'foo@bar.com' && req.body.password === 'foobar')) {  
  //   // Looks like the user provided invalid credentials, let's show the ui again...  
  
  //   res.render('login', {  
  //     csrfToken: req.csrfToken(),  
  
  //     challenge: challenge,  
  
  //     error: 'The username / password combination is not correct'  
  //   });  
  //   return;  
  // }  
  
  // Seems like the user authenticated! Let's tell hydra...  
  // hydra.acceptLoginRequest(challenge, {  
  //   // Subject is an alias for user ID. A subject can be a random string, a UUID, an email address, ....  
  //   subject: 'foo@bar.com',  
  
  //   // This tells hydra to remember the browser and automatically authenticate the user in future requests. This will  
  //   // set the "skip" parameter in the other route to true on subsequent requests!  
  //   remember: Boolean(req.body.remember),  
  
  //   // When the session expires, in seconds. Set this to 0 so it will never expire.  
  //   remember_for: 3600,  
  
  //   // Sets which "level" (e.g. 2-factor authentication) of authentication the user has. The value is really arbitrary  
  //   // and optional. In the context of OpenID Connect, a value of 0 indicates the lowest authorization level.  
  //   // acr: '0',  
  // })  
  //   .then(function (response) {  
  //     // All we need to do now is to redirect the user back to hydra!  
  //     res.redirect(response.redirect_to);  
  //   })  
  //   // This will handle any error that happens when making HTTP calls to hydra  
  //   .catch(function (error) {  
  //     next(error);  
  //   });  
  
  // You could also deny the login request which tells hydra that no one authenticated!  
  // hydra.rejectLoginRequest(challenge, {  
  //   error: 'invalid_request',  
  //   error_description: 'The user did something stupid...'  
  // })  
  //   .then(function (response) {  
  //     // All we need to do now is to redirect the browser back to hydra!  
  //     res.redirect(response.redirect_to);  
  //   })  
  //   // This will handle any error that happens when making HTTP calls to hydra  
  //   .catch(function (error) {  
  //     next(error);  
  //   });  
});  

https://t.tt:9010 When login id/pwd, can use adminer change database user email/password.