# PyBankID
![Build and Test](https://github.com/hbldh/pybankid/workflows/Build%20and%20Test/badge.svg)
![Documentation Status](https://readthedocs.org/projects/pybankid/badge/?version=latest)
![PyPI Version](https://img.shields.io/pypi/v/pybankid)
![PyPI License](https://img.shields.io/pypi/l/pybankid)
PyBankID is a client for providing BankID services as a Relying Party, i.e., providing authentication and signing functionality to end users. This package provides a simplifying interface for initiating authentication and signing orders and then collecting the results from the BankID servers.
The only supported BankID API version supported by PyBankID from version 1.0.0 is v6.0, which means that the Secure Start solution is the only supported way of providing BankID services. PyBankID versions prior to 1.0.0 will not work after 1st of May 2024.
If you intend to use PyBankID in your project, you are advised to read the [BankID Integration Guide](https://www.bankid.com/en/utvecklare/guider/teknisk-integrationsguide) before doing anything else. There, one can find information about how the BankID methods are defined and how to use them.
## Installation
PyBankID can be installed through pip:
```bash
pip install pybankid
```
## Usage
PyBankID provides both a synchronous and an asynchronous client for communication with BankID services. The example below will use the synchronous client, but the asynchronous client is used in an identical fashion, only using the `await` keyword before each function call.
### Synchronous client
```python
from bankid import BankIDClient
client = BankIDClient(certificates=(
'path/to/certificate.pem',
'path/to/key.pem',
))
```
Connection to the production server is the default in the client. If a test server is desired, send in the `test_server=True` keyword in the init of the client.
All authentication and signing calls require the end user's IP address to be included. An authentication order is initiated as such:
```python
client.authenticate(end_user_ip='194.168.2.25')
{
'orderRef': 'ee3421ea-2096-4000-8130-82648efe0927',
'autoStartToken': 'e8df5c3c-c67b-4a01-bfe5-fefeab760beb',
'qrStartToken': '01f94e28-857f-4d8a-bf8e-6c5a24466658',
'qrStartSecret': 'b4214886-3b5b-46ab-bc08-6862fddc0e06'
}
```
and a sign order is initiated in a similar fashion:
```python
client.sign(
end_user_ip='194.168.2.25',
user_visible_data="The information to sign."
)
{
'orderRef': 'ee3421ea-2096-4000-8130-82648efe0927',
'autoStartToken': 'e8df5c3c-c67b-4a01-bfe5-fefeab760beb',
'qrStartToken': '01f94e28-857f-4d8a-bf8e-6c5a24466658',
'qrStartSecret': 'b4214886-3b5b-46ab-bc08-6862fddc0e06'
}
```
If you want to ascertain that only one individual can authenticate or sign, you can specify this using the `requirement` keyword:
```python
client.sign(
end_user_ip='194.168.2.25',
user_visible_data="The information to sign."
requirement={"personalNumber": "YYYYMMDDXXXX"}
)
{
'orderRef': 'ee3421ea-2096-4000-8130-82648efe0927',
'autoStartToken': 'e8df5c3c-c67b-4a01-bfe5-fefeab760beb',
'qrStartToken': '01f94e28-857f-4d8a-bf8e-6c5a24466658',
'qrStartSecret': 'b4214886-3b5b-46ab-bc08-6862fddc0e06'
}
```
If someone other than the one you specified tries to authenticate or sign, the BankID app will state that the request is not intended for the user.
The status of an order can then be studied by polling with the `collect` method using the received `orderRef`:
```python
client.collect(order_ref="a9b791c3-459f-492b-bf61-23027876140b")
{
'hintCode': 'outstandingTransaction',
'orderRef': 'a9b791c3-459f-492b-bf61-23027876140b',
'status': 'pending'
}
```
```python
client.collect(order_ref="a9b791c3-459f-492b-bf61-23027876140b")
{
'hintCode': 'userSign',
'orderRef': 'a9b791c3-459f-492b-bf61-23027876140b',
'status': 'pending'
}
```
```python
client.collect(order_ref="a9b791c3-459f-492b-bf61-23027876140b")
{
'completionData': {
'cert': {
'notAfter': '1581289199000',
'notBefore': '1518130800000'
},
'device': {
'ipAddress': '0.0.0.0'
},
'ocspResponse': 'MIIHegoBAKCCB[...]',
'signature': 'PD94bWwgdmVyc2lv[...]',
'user': {
'givenName': 'Namn',
'name': 'Namn Namnsson',
'personalNumber': 'YYYYMMDDXXXX',
'surname': 'Namnsson'
}
},
'orderRef': 'a9b791c3-459f-492b-bf61-23027876140b',
'status': 'complete'
}
```
Please note that the `collect` method should be used sparingly: in the [BankID Integration Guide](https://www.bankid.com/en/utvecklare/guider/teknisk-integrationsguide) it is specified that _"collect should be called every two seconds and must not be called more frequent than once per second"_.
PyBankID also implements the `phone/auth` and `phone/sign` methods, for performing authentication and signing with
users that are contacted through phone. For documentation on this, see [PyBankID's Read the Docs page](https://pybankid.readthedocs.io/en/latest/).
### Asynchronous client
The asynchronous client is used in the same way as the synchronous client, with the difference that all request are performed asynchronously.
The synchronous guide above can be used as a reference for the asynchronous client as well, by simply adding the `await` keyword:
```python
from bankid import BankIDAsyncClient
client = BankIDAsyncClient(certificates=(
'path/to/certificate.pem',
'path/to/key.pem',
))
await client.authenticate(end_user_ip='194.168.2.25')
{
'orderRef': 'ee3421ea-2096-4000-8130-82648efe0927',
'autoStartToken': 'e8df5c3c-c67b-4a01-bfe5-fefeab760beb',
'qrStartToken': '01f94e28-857f-4d8a-bf8e-6c5a24466658',
'qrStartSecret': 'b4214886-3b5b-46ab-bc08-6862fddc0e06'
}
```
## PyBankID and QR codes
PyBankID can generate QR codes for you, and there is an example application in the [examples folder of the repo](https://github.com/hbldh/pybankid/tree/master/examples), where a Flask application called `qrdemo` shows one way to do authentication with animated QR codes.
The QR code content generation is done with the `generate_qr_code_content` method on the BankID Client instances, or directly
through the identically named method in `bankid.qr` module.
## Certificates
### Production certificates
If you want to use BankID in a production environment, then you will have to purchase this service from one of the [selling banks](https://www.bankid.com/foretag/anslut-foeretag). They will then provide you with a certificate that can be used to authenticate your company/application with the BankID servers.
This certificate has to be processed somewhat to be able to use with PyBankID, and how to do this depends on what the selling bank provides you with.
### Test certificate
The certificate to use when developing against the BankID test servers can be obtained through PyBankID:
```python
import os
import bankid
dir_to_save_cert_and_key_in = os.path.expanduser('~')
cert_and_key = bankid.create_bankid_test_server_cert_and_key(
dir_to_save_cert_and_key_in)
print(cert_and_key)
['/home/hbldh/certificate.pem', '/home/hbldh/key.pem']
client = bankid.BankIDClient(
certificates=cert_and_key, test_server=True)
```
Raw data
{
"_id": null,
"home_page": "https://github.com/hbldh/pybankid",
"name": "pybankid",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": null,
"author": "Henrik Blidh",
"author_email": "henrik.blidh@nedomkull.com",
"download_url": "https://files.pythonhosted.org/packages/c2/6f/7d5848934656a634ae617d96926dace003653245c622a92d357ca3e733e2/pybankid-1.4.1.tar.gz",
"platform": null,
"description": "\n# PyBankID\n\n![Build and Test](https://github.com/hbldh/pybankid/workflows/Build%20and%20Test/badge.svg)\n![Documentation Status](https://readthedocs.org/projects/pybankid/badge/?version=latest)\n![PyPI Version](https://img.shields.io/pypi/v/pybankid)\n![PyPI License](https://img.shields.io/pypi/l/pybankid)\n\nPyBankID is a client for providing BankID services as a Relying Party, i.e., providing authentication and signing functionality to end users. This package provides a simplifying interface for initiating authentication and signing orders and then collecting the results from the BankID servers.\n\nThe only supported BankID API version supported by PyBankID from version 1.0.0 is v6.0, which means that the Secure Start solution is the only supported way of providing BankID services. PyBankID versions prior to 1.0.0 will not work after 1st of May 2024.\n\nIf you intend to use PyBankID in your project, you are advised to read the [BankID Integration Guide](https://www.bankid.com/en/utvecklare/guider/teknisk-integrationsguide) before doing anything else. There, one can find information about how the BankID methods are defined and how to use them.\n\n## Installation\n\nPyBankID can be installed through pip:\n\n```bash\npip install pybankid\n```\n\n## Usage\n\nPyBankID provides both a synchronous and an asynchronous client for communication with BankID services. The example below will use the synchronous client, but the asynchronous client is used in an identical fashion, only using the `await` keyword before each function call.\n\n### Synchronous client\n\n```python\nfrom bankid import BankIDClient\nclient = BankIDClient(certificates=(\n 'path/to/certificate.pem',\n 'path/to/key.pem',\n))\n```\n\nConnection to the production server is the default in the client. If a test server is desired, send in the `test_server=True` keyword in the init of the client.\n\nAll authentication and signing calls require the end user's IP address to be included. An authentication order is initiated as such:\n\n```python\nclient.authenticate(end_user_ip='194.168.2.25')\n{\n 'orderRef': 'ee3421ea-2096-4000-8130-82648efe0927',\n 'autoStartToken': 'e8df5c3c-c67b-4a01-bfe5-fefeab760beb',\n 'qrStartToken': '01f94e28-857f-4d8a-bf8e-6c5a24466658',\n 'qrStartSecret': 'b4214886-3b5b-46ab-bc08-6862fddc0e06'\n}\n```\n\nand a sign order is initiated in a similar fashion:\n\n```python\nclient.sign(\n end_user_ip='194.168.2.25',\n user_visible_data=\"The information to sign.\"\n)\n{\n 'orderRef': 'ee3421ea-2096-4000-8130-82648efe0927',\n 'autoStartToken': 'e8df5c3c-c67b-4a01-bfe5-fefeab760beb',\n 'qrStartToken': '01f94e28-857f-4d8a-bf8e-6c5a24466658',\n 'qrStartSecret': 'b4214886-3b5b-46ab-bc08-6862fddc0e06'\n}\n```\n\nIf you want to ascertain that only one individual can authenticate or sign, you can specify this using the `requirement` keyword:\n\n```python\nclient.sign(\n end_user_ip='194.168.2.25',\n user_visible_data=\"The information to sign.\"\n requirement={\"personalNumber\": \"YYYYMMDDXXXX\"}\n)\n{\n 'orderRef': 'ee3421ea-2096-4000-8130-82648efe0927',\n 'autoStartToken': 'e8df5c3c-c67b-4a01-bfe5-fefeab760beb',\n 'qrStartToken': '01f94e28-857f-4d8a-bf8e-6c5a24466658',\n 'qrStartSecret': 'b4214886-3b5b-46ab-bc08-6862fddc0e06'\n}\n```\n\nIf someone other than the one you specified tries to authenticate or sign, the BankID app will state that the request is not intended for the user.\n\nThe status of an order can then be studied by polling with the `collect` method using the received `orderRef`:\n\n```python\nclient.collect(order_ref=\"a9b791c3-459f-492b-bf61-23027876140b\")\n{\n 'hintCode': 'outstandingTransaction',\n 'orderRef': 'a9b791c3-459f-492b-bf61-23027876140b',\n 'status': 'pending'\n}\n```\n\n```python\nclient.collect(order_ref=\"a9b791c3-459f-492b-bf61-23027876140b\")\n{\n 'hintCode': 'userSign',\n 'orderRef': 'a9b791c3-459f-492b-bf61-23027876140b',\n 'status': 'pending'\n}\n```\n\n```python\nclient.collect(order_ref=\"a9b791c3-459f-492b-bf61-23027876140b\")\n{\n 'completionData': {\n 'cert': {\n 'notAfter': '1581289199000',\n 'notBefore': '1518130800000'\n },\n 'device': {\n 'ipAddress': '0.0.0.0'\n },\n 'ocspResponse': 'MIIHegoBAKCCB[...]',\n 'signature': 'PD94bWwgdmVyc2lv[...]',\n 'user': {\n 'givenName': 'Namn',\n 'name': 'Namn Namnsson',\n 'personalNumber': 'YYYYMMDDXXXX',\n 'surname': 'Namnsson'\n }\n },\n 'orderRef': 'a9b791c3-459f-492b-bf61-23027876140b',\n 'status': 'complete'\n}\n```\n\nPlease note that the `collect` method should be used sparingly: in the [BankID Integration Guide](https://www.bankid.com/en/utvecklare/guider/teknisk-integrationsguide) it is specified that _\"collect should be called every two seconds and must not be called more frequent than once per second\"_.\n\nPyBankID also implements the `phone/auth` and `phone/sign` methods, for performing authentication and signing with\nusers that are contacted through phone. For documentation on this, see [PyBankID's Read the Docs page](https://pybankid.readthedocs.io/en/latest/).\n\n### Asynchronous client\n\nThe asynchronous client is used in the same way as the synchronous client, with the difference that all request are performed asynchronously.\n\nThe synchronous guide above can be used as a reference for the asynchronous client as well, by simply adding the `await` keyword:\n\n```python\nfrom bankid import BankIDAsyncClient\nclient = BankIDAsyncClient(certificates=(\n 'path/to/certificate.pem',\n 'path/to/key.pem',\n))\n\nawait client.authenticate(end_user_ip='194.168.2.25')\n{\n 'orderRef': 'ee3421ea-2096-4000-8130-82648efe0927',\n 'autoStartToken': 'e8df5c3c-c67b-4a01-bfe5-fefeab760beb',\n 'qrStartToken': '01f94e28-857f-4d8a-bf8e-6c5a24466658',\n 'qrStartSecret': 'b4214886-3b5b-46ab-bc08-6862fddc0e06'\n}\n```\n\n## PyBankID and QR codes\n\nPyBankID can generate QR codes for you, and there is an example application in the [examples folder of the repo](https://github.com/hbldh/pybankid/tree/master/examples), where a Flask application called `qrdemo` shows one way to do authentication with animated QR codes.\n\nThe QR code content generation is done with the `generate_qr_code_content` method on the BankID Client instances, or directly\nthrough the identically named method in `bankid.qr` module.\n\n## Certificates\n\n### Production certificates\n\nIf you want to use BankID in a production environment, then you will have to purchase this service from one of the [selling banks](https://www.bankid.com/foretag/anslut-foeretag). They will then provide you with a certificate that can be used to authenticate your company/application with the BankID servers.\n\nThis certificate has to be processed somewhat to be able to use with PyBankID, and how to do this depends on what the selling bank provides you with.\n\n### Test certificate\n\nThe certificate to use when developing against the BankID test servers can be obtained through PyBankID:\n\n```python\nimport os\nimport bankid\ndir_to_save_cert_and_key_in = os.path.expanduser('~')\ncert_and_key = bankid.create_bankid_test_server_cert_and_key(\n dir_to_save_cert_and_key_in)\nprint(cert_and_key)\n['/home/hbldh/certificate.pem', '/home/hbldh/key.pem']\nclient = bankid.BankIDClient(\n certificates=cert_and_key, test_server=True)\n```\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "BankID Relying Party client for Python",
"version": "1.4.1",
"project_urls": {
"Homepage": "https://github.com/hbldh/pybankid"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "0e61f56721477566b16d71426ac988f25fae6eaba13dfc727726cfaae8c664b6",
"md5": "b256e04835b3a834bfe3fd6c65e3c60f",
"sha256": "c25575714daf7400598869027c227921e020e576a8772d564de134cf33250255"
},
"downloads": -1,
"filename": "pybankid-1.4.1-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "b256e04835b3a834bfe3fd6c65e3c60f",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": null,
"size": 35551,
"upload_time": "2024-12-09T14:27:43",
"upload_time_iso_8601": "2024-12-09T14:27:43.311074Z",
"url": "https://files.pythonhosted.org/packages/0e/61/f56721477566b16d71426ac988f25fae6eaba13dfc727726cfaae8c664b6/pybankid-1.4.1-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "c26f7d5848934656a634ae617d96926dace003653245c622a92d357ca3e733e2",
"md5": "215109a96a7c7e7dde4a0f5e86b0f872",
"sha256": "e8d6e86d6ec441ddd0f1477eb4b1a692375b187b48d211991fb5c13ab211be80"
},
"downloads": -1,
"filename": "pybankid-1.4.1.tar.gz",
"has_sig": false,
"md5_digest": "215109a96a7c7e7dde4a0f5e86b0f872",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 47426,
"upload_time": "2024-12-09T14:27:45",
"upload_time_iso_8601": "2024-12-09T14:27:45.314953Z",
"url": "https://files.pythonhosted.org/packages/c2/6f/7d5848934656a634ae617d96926dace003653245c622a92d357ca3e733e2/pybankid-1.4.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-12-09 14:27:45",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "hbldh",
"github_project": "pybankid",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"requirements": [
{
"name": "httpx",
"specs": []
},
{
"name": "importlib_resources",
"specs": []
}
],
"lcname": "pybankid"
}