Builder.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. <?php
  2. /**
  3. * This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
  4. *
  5. * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
  6. */
  7. namespace Lcobucci\JWT;
  8. use BadMethodCallException;
  9. use Lcobucci\JWT\Claim\Factory as ClaimFactory;
  10. use Lcobucci\JWT\Parsing\Encoder;
  11. /**
  12. * This class makes easier the token creation process
  13. *
  14. * @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
  15. * @since 0.1.0
  16. */
  17. class Builder
  18. {
  19. /**
  20. * The token header
  21. *
  22. * @var array
  23. */
  24. private $headers;
  25. /**
  26. * The token claim set
  27. *
  28. * @var array
  29. */
  30. private $claims;
  31. /**
  32. * The token signature
  33. *
  34. * @var Signature
  35. */
  36. private $signature;
  37. /**
  38. * The data encoder
  39. *
  40. * @var Encoder
  41. */
  42. private $encoder;
  43. /**
  44. * The factory of claims
  45. *
  46. * @var ClaimFactory
  47. */
  48. private $claimFactory;
  49. /**
  50. * Initializes a new builder
  51. *
  52. * @param Encoder $encoder
  53. * @param ClaimFactory $claimFactory
  54. */
  55. public function __construct(
  56. Encoder $encoder = null,
  57. ClaimFactory $claimFactory = null
  58. ) {
  59. $this->encoder = $encoder ?: new Encoder();
  60. $this->claimFactory = $claimFactory ?: new ClaimFactory();
  61. $this->headers = ['typ'=> 'JWT', 'alg' => 'none'];
  62. $this->claims = [];
  63. }
  64. /**
  65. * Configures the audience
  66. *
  67. * @param string $audience
  68. * @param boolean $replicateAsHeader
  69. *
  70. * @return Builder
  71. */
  72. public function setAudience($audience, $replicateAsHeader = false)
  73. {
  74. return $this->setRegisteredClaim('aud', (string) $audience, $replicateAsHeader);
  75. }
  76. /**
  77. * Configures the expiration time
  78. *
  79. * @param int $expiration
  80. * @param boolean $replicateAsHeader
  81. *
  82. * @return Builder
  83. */
  84. public function setExpiration($expiration, $replicateAsHeader = false)
  85. {
  86. return $this->setRegisteredClaim('exp', (int) $expiration, $replicateAsHeader);
  87. }
  88. /**
  89. * Configures the token id
  90. *
  91. * @param string $id
  92. * @param boolean $replicateAsHeader
  93. *
  94. * @return Builder
  95. */
  96. public function setId($id, $replicateAsHeader = false)
  97. {
  98. return $this->setRegisteredClaim('jti', (string) $id, $replicateAsHeader);
  99. }
  100. /**
  101. * Configures the time that the token was issued
  102. *
  103. * @param int $issuedAt
  104. * @param boolean $replicateAsHeader
  105. *
  106. * @return Builder
  107. */
  108. public function setIssuedAt($issuedAt, $replicateAsHeader = false)
  109. {
  110. return $this->setRegisteredClaim('iat', (int) $issuedAt, $replicateAsHeader);
  111. }
  112. /**
  113. * Configures the issuer
  114. *
  115. * @param string $issuer
  116. * @param boolean $replicateAsHeader
  117. *
  118. * @return Builder
  119. */
  120. public function setIssuer($issuer, $replicateAsHeader = false)
  121. {
  122. return $this->setRegisteredClaim('iss', (string) $issuer, $replicateAsHeader);
  123. }
  124. /**
  125. * Configures the time before which the token cannot be accepted
  126. *
  127. * @param int $notBefore
  128. * @param boolean $replicateAsHeader
  129. *
  130. * @return Builder
  131. */
  132. public function setNotBefore($notBefore, $replicateAsHeader = false)
  133. {
  134. return $this->setRegisteredClaim('nbf', (int) $notBefore, $replicateAsHeader);
  135. }
  136. /**
  137. * Configures the subject
  138. *
  139. * @param string $subject
  140. * @param boolean $replicateAsHeader
  141. *
  142. * @return Builder
  143. */
  144. public function setSubject($subject, $replicateAsHeader = false)
  145. {
  146. return $this->setRegisteredClaim('sub', (string) $subject, $replicateAsHeader);
  147. }
  148. /**
  149. * Configures a registed claim
  150. *
  151. * @param string $name
  152. * @param mixed $value
  153. * @param boolean $replicate
  154. *
  155. * @return Builder
  156. */
  157. protected function setRegisteredClaim($name, $value, $replicate)
  158. {
  159. $this->set($name, $value);
  160. if ($replicate) {
  161. $this->headers[$name] = $this->claims[$name];
  162. }
  163. return $this;
  164. }
  165. /**
  166. * Configures a header item
  167. *
  168. * @param string $name
  169. * @param mixed $value
  170. *
  171. * @return Builder
  172. *
  173. * @throws BadMethodCallException When data has been already signed
  174. */
  175. public function setHeader($name, $value)
  176. {
  177. if ($this->signature) {
  178. throw new BadMethodCallException('You must unsign before make changes');
  179. }
  180. $this->headers[(string) $name] = $this->claimFactory->create($name, $value);
  181. return $this;
  182. }
  183. /**
  184. * Configures a claim item
  185. *
  186. * @param string $name
  187. * @param mixed $value
  188. *
  189. * @return Builder
  190. *
  191. * @throws BadMethodCallException When data has been already signed
  192. */
  193. public function set($name, $value)
  194. {
  195. if ($this->signature) {
  196. throw new BadMethodCallException('You must unsign before making changes');
  197. }
  198. $this->claims[(string) $name] = $this->claimFactory->create($name, $value);
  199. return $this;
  200. }
  201. /**
  202. * Signs the data
  203. *
  204. * @param Signer $signer
  205. * @param string $key
  206. *
  207. * @return Builder
  208. */
  209. public function sign(Signer $signer, $key)
  210. {
  211. $signer->modifyHeader($this->headers);
  212. $this->signature = $signer->sign(
  213. $this->getToken()->getPayload(),
  214. $key
  215. );
  216. return $this;
  217. }
  218. /**
  219. * Removes the signature from the builder
  220. *
  221. * @return Builder
  222. */
  223. public function unsign()
  224. {
  225. $this->signature = null;
  226. return $this;
  227. }
  228. /**
  229. * Returns the resultant token
  230. *
  231. * @return Token
  232. */
  233. public function getToken()
  234. {
  235. $payload = [
  236. $this->encoder->base64UrlEncode($this->encoder->jsonEncode($this->headers)),
  237. $this->encoder->base64UrlEncode($this->encoder->jsonEncode($this->claims))
  238. ];
  239. if ($this->signature !== null) {
  240. $payload[] = $this->encoder->base64UrlEncode($this->signature);
  241. }
  242. return new Token($this->headers, $this->claims, $this->signature, $payload);
  243. }
  244. }