1

Spring を使用して Web アプリケーションを作成しようとしています。Web アプリケーションは、招待制のベータ版/デモ サイトです。そのため、24 時間有効な一意の ID を追加して、Web アプリケーションの URL へのリンクを生成する必要があります。ユーザーはそのリンクを 24 時間使用できます (IP でユーザーを制限する計画もあります)。

このようなトークンの生成と有効期限を達成するには、セッション タイムアウトのあるコンテナーに依存する必要がありますか? または、トークンの作成と有効期限サービスを備えたスプリング バックアップ サービス レイヤーを作成することは理にかなっていますか?

編集

より注目を集めるための報奨金が得られたので、より意味のある質問を言い換えてみようと思いました - 一定期間後にユーザーを強制的に Web アプリケーションから除外するには、どのような戦略がよいでしょうか?

4

7 に答える 7

3

Cookie のセッションではなく、バックエンドにもっと依存する必要があると思います。Cookie の有効期限を 24 時間に設定したが、クライアントがブラウザーから Cookie を削除した場合を想像してください (ロジックによっては) リンク新しいセッションが生成されるか、リクエストがブロックされます。

私見では、クライアントにセッション Cookie を保存できますが、サーバーに 2 番目の比較ソース、おそらくデータベース、no-sql ドキュメント、キャッシュ内のコレクション、比較して最新のアクセスを確認できるものを用意する必要があります。クライアント。

すべてをまとめるために、次の使用例を想像してください。

  • ユーザーは招待リンクを取得し、それをクリックします
  • システムは、ユーザーがシステムに初めてログインしたかどうかをチェックし、その日付を「開始日」として保存し、別の日付を「最終アクセス」として保存します。
  • システムは、有効期限が 24 時間の認証 Cookie を設定します。
  • システムはサーバーへのすべてのポストバック/ ajax 呼び出しを追跡し、「最終アクセス」日付を更新します
  • ユーザーが Cookie を削除すると、システムは「最終アクセス」をチェックし、現在のサーバーの日付と比較します
  • 有効な場合、システムは残りの時間で新しい認証 Cookie を作成します
  • 有効でない場合、システムはユーザーにメッセージを送信します。
  • ユーザーの場合、Cookie は残り時間 (開始日と最終アクセスの間の計算) に従って期限切れになります。

これが役立つことを願っています。よろしく

于 2013-09-24T19:26:26.943 に答える
3

1 つの戦略は、関連するデータを DB に格納し、キャッシュ ライブラリを使用してすべてのユーザーを追跡することexpiry date-timeです (有効期限をチェックしながら DB ヒットを減らすため)。以下に小さな例を示します。

ユーザー ID を有効期限にマップする列を持つ DB テーブルを作成します: id, unique_user_id, expiry_date_time。この ID を持つユーザーに URL を送信する前に、コードで一意のユーザー ID を作成し、DB に保存する必要があります。nullの初期値として保持できますexpiry_date_time。Java でこのマッピングを表すクラスを作成します。

class UserIdWithExpiryDate{
        private String userId;
        private Date expiryDateTime;
        ...
}

指定されたに対して this のインスタンスを返すメソッドで を定義しServiceます。cacheableuserId

public interface CacheableService {
    @Cacheable("expiryDates")
    public UserIdWithExpiryDate getUserIdWithExpiryDate(String id);

    public void updateUserIdWithExpiryDate(String userId);
}

import org.joda.time.DateTime;
@Service
public class CacheableServiceImpl implements CacheableService {

    @Autowired
    private YourDao dao;

    @Override
    public UserIdWithExpiryDate getUserIdWithExpiryDate(String id) {
        return dao.getUserIdWithExpiryDate(id);
    }

    public void updateUserIdWithExpiryDate(String userId){
        Date expiryDate = new Date(new DateTime().plusHours(24).getMillis());
        dao.update(userId, expiryDate);
    }
}

メソッドの結果はgetUserIdWithExpiryDateキャッシュに格納されるため、後続の呼び出し (同じ引数を使用) では、メソッドを実際に実行しなくてもキャッシュ内の値が返されます。

次のステップは、サイトへのアクセス中にユーザーの有効期限を確認することです。これは、OncePerRequestFilterを使用して実行できます。

@Component("timeoutFilter")
public class TimeoutFilter extends OncePerRequestFilter {

    @Autowired
    CacheableService cacheableService;
    // Here you need to decide whether to proceed with the request or not
    @Override
    protected void doFilterInternal(HttpServletRequest request,
            HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        filterChain.doFilter(request, response);
    }

}

doFilterInternalユーザーの有効性を確認するためにメソッド内で実行できる手順は次のとおりです。

  1. リクエストからユーザー ID を取得する
  2. 実行する:cacheableService.getUserIdWithExpiryDate(userId)
  3. ステップ 2 で null が返された場合、この ID を持つユーザーは存在しません。リクエストを続行しないでください。
  4. ステップ 2 で UserIdWithExpiryDate のインスタンスが返された場合は、「expiryDateTime」の値を確認します。
  5. 「expiryDateTime」の値が null の場合、ユーザーが初めてサイトにアクセスしていることを意味します。「userExpiryDate」:cacheableService.updateUserIdWithExpiryDate(userId) を更新し、リクエストを続行します。
  6. 「expiryDateTime」が null でない場合は、これを現在の date_time と比較します。の場合expiryDateTime.isAfter(currentDateTime)は、リクエストを続行します。

キャッシングには、EHCACHEでSpring Cache Abstractionを使用できます。

于 2013-09-26T13:27:19.943 に答える
2

ここで、私が見た 2 つの使用例を考えることができます。

1.)この種の管理は、オンライン テストや電子メール検証などのアプリケーションで使用され、ユーザーは何らかのトークン付きのリンクを提供されます。このリンクとトークンは一定期間有効で、一度だけ使用できます。(例: オンライン テストまたはパスワード リセット メール)

2.)別のユースケースは、一定期間有効なトークンとのリンクを提供することですが、この場合、リンクとトークンは許可された期間内であれば何度でも使用できます (例: オンライン登録)テストまたは一部の大学への入学のためのフォーム)。

したがって、セッションのみを使用してこれを管理することは、ブラウザをクリアできるため、適切な選択ではありません。したがって、リンクとトークンのペアをサーバー (DB にある場合もあります) で、最終アクセス時刻作成日時有効期限などの他の情報とともに維持する必要があります。

リンクとトークンの有効期間をより柔軟にするために、別の方法で設定できます (たとえば、リンクは一連のユーザーに使用できますが、トークンはユーザーに固有です)。

そのため、ユーザーがアクセスするたびにこの情報を使用して、リンクまたはトークンがまだ有効かどうか、最後にアクセスした時刻を確認できます。有効期限が切れていることが判明した場合は、関連するエラー メッセージを表示できます。

于 2013-09-26T07:26:50.847 に答える